免费注册 登录
»专业资料»IT/计算机»计算机软件及应用»java基础知识点总结.docx
收起/展开

java基础知识点总结

文档类型:docx 上传时间:2018-08-26 文档页数:31页 文档大小:62.62 K 文档浏览:3118次 文档下载:0次 所需积分:0 学币 文档评分:3.0星

java基础知识点总结内容摘要: Created by AIwen on 2017/5/14.java 是面向对象的程序设计语言;类可被认为是一种自定义的数据类型,可以使用类来定义变量,所有使用类定义的变量都是引用变量,它们将会引用到类的对象。类用于描述客观世界里某一类对象的共同特征,而对象则是类的具体存在,java 程序使用类的构造器来创建该类的对象。java 也支持面向对象的三大特征:封装、继承、和多态。java 提供了 private、protected、和 public 三个访问控制修饰符来实现良好的封装,提供了 extends 关键字让子类继承父类,子类继承父类就可以继承到父类的成员变量和和方法,如果访问控制允许,子类实例可以直接调用父类里定义的方法。继承是实现类复用的重要手段。使用继承关系来实现复用时,子类对象可以直接赋给父类变量,这个变量具有多态性。面向对象的程序设计过程中有两个重要的概念:类(Class)和对象(object,也被称为实例,instance)。类可以包含三种最常见的成员:构造器、成员变量、和方法。构造器用于构造该类的实例,java 语言通过 new 关键字类调用构造器,从而返回该类的实例。构造器是一个类创建对象的根本途径,如果一个类没有构造器,这个类通常无法创建实例。因此 java 语言提供了一个功能:如果程序员没有为一个类编写构造器,则系统会为该类提供一个默认的构造器,这个构造器总是没有参数的。一旦程序员为一个类提供了构造器,系统将不再为该类提供构造器。构造器用于对类实例进行初始化操作,构造器支持重载,如果多个重载的构造器里包含了相同的初始化代码,则可以把这些初始化代码放置在普通初始化块里完成,初始化块总在构造器执行之前被调用。静态初始化块代码用于初始化类,在类初始化阶段被执行。如果继承树里某一个类需要被初始化时,系统将会同时初始化该类的所有父类。构造器修饰符:可以是 public、protected、private 其中之一,或者省略构造器名:构造器名必须和类名相同。注意:构造器既不能定义返回值类型,也不能使用 void 声明构造器没有返回值。如果为构造器定义了返回值类型,或使用 void 声明构造器没有返回值,编译时不会出错,但 java 会把这个所谓的构造器当成方法来处理 它就不——再是构造器。实际上类的构造器是有返回值的,当使用 new 关键字来调用构造器时,构造器返回该类的实例,可以把这个类的实例当成构造器的返回值。因此构造器的返回值类型总是当前类,无须定义返回值类型。不要在构造器里显式的使用return 来返回当前类的对象,因为构造器的返回值是隐式的。java 类名必须是由一个或多个有意义的单词连缀而成的,每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。成员变量:成员变量的修饰符:public、protected、private、static、final 前三个只能出现一个再和后面的修饰符组合起来修饰成员变量,也可省略。成员变量:由一个或者多个有意义的单词连缀而成,第一个单词首字母小写,后面每个单词首字母大写,其他字母全部小写,单词与单词之间不要使用任何分隔符。类型:可以是 java 语言允许的任何数据类型,包括基本类型和引用类型。成员方法:方法修饰符:public、protected、private、static、final、abstract,前三个只能出现一个,static 和final 最多只能出现其中的一个,和 abstract 组合起来使用。也可省略。返回值类型:可以是 java 语言的允许的任何数据类型,包括基本类型和引用类型。方法名:和成员变量的方法命名规则相同,通常建议方法名以英文动词开头。方法体里多条可执行语句之间有严格的执行顺序,排在方法体前面的语句总先执行,排在方法体后面的语句总是后执行。static 是一个特殊的关键字,它可用于修饰方法、成员变量等成员。static 修饰的成员表明它属于这个类本身,而不属于该类的单个实例,因此通过把 static 修饰的成员变量和方法被称为类变量、类方法(静态成员变量,静态成员方法);不使用 static 修饰的成员变量和方法称为实例变量和实例方法(非静态成员变量,非静态成员方法)。静态成员不能直接访问非静态成员。static 的真正作用就是用于区分成员变量、方法、内部类、初始化块,这四种成员到底属于类本身还是属于实例。有 static 修饰的成员属于 类本身,没有类修饰的成员属于该类的实例。java 类大致有如下作用:定义变量创建对象调用类的类方法或访问类的类变量。定义一个类就是为了重复创建该类的实例,同一个类的多个实例具有相同的特征,而类则是定义了多个实例的共同特征。类里定义的方法和成员变量都可以通过类或实例来调用。Static 修饰的方法和成员变量,既可通过类来调用,也可通过实例来调用;没有使用 static 修饰的普通方法成员变量,只可通过实例来调用。Person p=new Person();这行代码创建了一个 Person 实例,也被称为 Person 对象,这个 Person 对象被赋给 p 变量。在这行代码中实际上产生了两个东西,一个是 p 变量,一个是 Person 对象。P 引用变量本身只存储了一个地址值,并未包含任何实际数据,但它指向实际的 Person 对象。Person 对象由多块内存组成,不同内存块分别存储了 Person 对象的不同成员变量。类是一种引用数据类型,因此程序中定义的 Person 类型的变量实际上是一个引用,它被存放在栈内存里,指向实际的 Person 对象;而真正的 Person 对象则存放在堆内存中。当一个对象被创建成功以后,这个对象将保存在堆内存中,java 程序不允许直接访问堆内存中的对象,只能通过该对象的引用操作该对象。堆内存里的对象可以有多个引用,即多个引用变量指向同一个对象。如果堆内存里的对象没有任何变量指向该对象,那么程序将无法再访问该对象,这个对象也就变成了垃圾,java 垃圾回收机制将回收该对象,释放该对象所占的内存区。对象的 this 引用Java 提供了一个 this 关键字,this 关键字总是指向调用该方法的对象。This 作为对象的默认引用有两种情形:构造器中引用该构造器正在初始化的对象;在方法中引用调用该方法的对象。This 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或者实例变量。Java 允许对象的一个成员直接调用另一个成员,可以省略 this前缀。如果在 static 修饰的方法中使用 this 关键字,则这个关键字就无法指向合适的对象,所以,static 修饰的方法中不能使用 this 引用。Java 编程时不要使用对象去调用 static 修饰的成员变量、方法、而是应该使用类去调用 static 修饰的成员变量、方法。如果确实需要在静态方法中访问另一个普通方法,则只能重新创建一个对象。大部分的时候,普通方法访问其他方法、成员变量时无须使用 this 前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用 this 前缀。This 引用也可以用于构造器中作为默认引用,由于构造器时直接使用 new 关键字来调用,而不是使用对象来调用的,所以 this 在构造器中代表该构造器正在初始化对象。方法:Java 里的方法不能独立存在,所有的方法都必须定义在类里。如果这个方法是用来 static 修饰,则这个方法属于这个类,否则这个方法属于这个类的实例。执行方法时,必须使用类或者对象作为调用者。同一个类的一个方法调用另外一个方法时,如果被调方法是普通方法,则默认使用 this 作为调用者;如果被调用方法是静态方法,则默认使用类作为调用者。也就是说 java 中看起来某些方法可以被独立执行,但实际上还是使用 this 或者类来作为调用者。Java 里方法参数传递方式只有一种:值传递。所谓值传递,就是讲实际参数值的副本(复制品)传入方法内,而参数本身不会受到任何影响。从 JDK1.5 之后,java 允许定义形参个数可变的参数,从而允许为方法指定数量不确定的形参。如果在定义方法时,在最后一个形参的类型后增加三点( )… ,则表明该形参可以接受多个参数值,多个参数值被当成数组传入。public class Varargs {//定义形参可变的方法public static void test(int a,String... books){//books 被当成数组处理for(String tmp:books){System.out.println(tmp);}System.out.println(a);}public static void main(String[] args){//调用 test 方法test(5,"hello","world","aa");}}数组形式的形参可以处于形参列表的任意位置,但个数可变的形参只能处于形参表的最后。也就是说最多只能有一个长度可变的形参。形参可变和传入数组的区别:public static void test(int a,String... books);public static void test(int a,String[] books);test(5,"aa","bb","cc");test(5,new String[]{"aa","bb","cc"});方法重载:Java 允许同一个类里定义多个同名方法,只要形参列表不同就行。如果同一个类中包含了两个或两个以上方法的方法名相同,但形参列表不同,则被称为方法的重载。Java 程序确定一个方法需要三个要素:调用者;方法名;形参列表。方法的重载要求就是两同一不同:同一个类中方法名相同,参数列表不同。至于方法的其他部分,如方法返回值类型、修饰符等,与方法重载没有任何关系。public class OverloadVarargs {public void test(String msg){System.out.println("只有一个参数的 test");}//因为前面已经有了一个字符串参数的方法,则长度可变形参里不包含一个字符串参数的形式public void test(String ...books){System.out.println("形参可变的 test 方法");}public static void main(String[] args){OverloadVarargs olv=new OverloadVarargs();//下面两次调用将执行第二个 test 方法olv.test();olv.test("aa","bb");//将调用第一个 test 方法olv.test("aa");//将调用第二个 test 方法olv.test(new String[]{"aa"});}}Java 中变量分为:成员变量和局部变量。成员变量被分为类变量和实例变量两种,定义成员变量时没有 static 修饰的就是实例变量,有 static 修饰的就是类变量。 变量的命名:从程序的可读性角度来看,应该是多个有意义的单词连缀而成,其中第一个单词首字母小写,后面每个单词首字母大写。 如果通过一个实例修改了类变量的值,由于这个类变量并不属于它,而是属于它对应的类。因此,修改的依然是类变量,与通过该类来修改类变量的结果完全相同,这会导致该类的其他实例来访问这个类变量时也将获得这个被修改过的值。 成员变量无须显式初始化,只要为一个类定义了类变量或实例变量,系统就会在这个类的初始化阶段或创建该类的实例时,进行默认初始化。 实例变量随实例的存在而存在,而类变量则随类的存在而存在。实例也可访问类变量,同一个类的所有实例访问类变量时,实际上访问的是该类本身的同一个变量,也就是说,访问了同一片内存区。 局部变量根据定义形式的不同,又可分为三种形式:形参,方法局部变量,代码块局部变量;局部变量除了形参之外,都必须显示初始化。 在同一个类里,成员变量的作用范围是整个类内有效,一个类里不能定义两个同名的成员变量,即使一个是类变量,一个是实例变量也不行;一个方法里不能定义两个同名的方法局部变量,方法局部变量与形参也不能同名;同一个方法中不同代码块内局部变量可以同名;如果先定义代码块局部变量,后定义方法局部变量,前面定义的代码块局部变量与后面定义的方法局部变量也可同名. Java 允许局部变量和成员变量同名,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员变量,如果需要在这个方法里引用被覆盖的成员变量,则可使用 this(对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。public class VariableOverrideTest {//定义一个 name 实例变量private String name="李刚";//定义一个 price 类变量private static double price=78.0;public static void main(String[] args){//方法里局部变量覆盖成员变量,将输出 price 的局部变量 65int price=65;System.out.println(price);//使用类名作为 price 变量的限定,将输出 price 类变量的值System.out.println(VariableOverrideTest.price);new VariableOverrideTest().info();}public void info(){//方法里的局部变量,局部变量覆盖成员变量,输出 name 局部变量的值:孙悟空String name="孙悟空";System.out.println(name);//将输出 name 实例的值:李刚System.out.println(this.name);}}当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值。Person p1=new Person();时,如果这行代码是第一次使用 Person 类,则系统通常会在第一次使用 Person类时加载这个类,并初始化这个类。局部变量定以后,必须经过显式初始化后才能使用,系统不会为局部变量执行初始化。局部变量不属于任何类或者实例,因此它总是保存在其所在方法的栈内存中。如果局部变量时基本类型的变量,则直接把这个变量的值保存在该变量对应的内存中;如果局部变量是一个引用类型的变量,则这个变量里存放的是地址,通过该地址引用到该变量实际引用的对象或者数组。栈内存中的变量无须系统垃圾回收,往往随是方法或代码块的运行结束而结束。如果定义的某个变量是用于描述某个类或某个对象的固有信息的,这种变量应该定义成成员变量。如果这种信息对这个类的所有实例完全相同,或者说它是类相关的,则该定义成类变量;如果这个信息是实例相关的,则应该定义成实例变量。用于保存某个类或某个实例状态信息的变量通常应该使用成员变量。如果某个信息需要在某个类的多个方法之间进行共享,则这个信息应该使用成员变量来保存。隐藏和封装访问控制符用于控制一个类的成员是否可以被其他类访问。Java 提供了 3 个访问控制修饰符:private,protected,和 public,还有一个默认访问控制修饰符 defaultPrivate(当前类访问权限);default(包访问权限);protected(子类访问权限):如果一个成员使用protected 访问修饰符修饰,那么这个成员既可以被同一个包中的其他类访问,也可以被不同包中子类访问。 通常情况下,使用 protected 修饰的方法,通常希望其子类来重写这个方法。Public(公共访问权限)对于局部变量而言,其作用域就是它所在的方法,不可能被其他类访问,因此不能使用访问控制符来修饰。外部类只能有两种访问控制级别:public 和默认,不能使用 private 和 protectedpublic class Person {private String name;private int age;public void setName(String name){if(name.length()>6||name.length() 100 || age 5);//两个包装类实例进行比较时,只有两个包装类引用指向同一个对象时才返回 tureSystem.out.println(new Integer(2)==new Integer(2));}}系统把一个-128-127 之间的证书自动装箱成 Integer 实例,并放入了一个名为 cache 的数组中缓存起来。如果以后把一个-128-127 之间的整数自动装箱成一个 Integer 实例时,实际上是直接指向对应的数组元素,因此-128-127 之间的同一个整数自动装箱成 Integer 实例时,永远都是引用 cache 数组的同一个数组元素,所以它们都相等。但如果整数不在这个范围内,则会重新创建一个 Integer 实例。public class TestDmo2 {public static void main(String[] args){Integer a=2;Integer b=2;System.out.println(a==b); //trueInteger biga=128;Integer bigb=128;System.out.println(biga==bigb); //false}}5.2 处理对象对象打印的误区:public class PrintObject {public static void main(String[] args){Person p=new Person("Peter");//如果想打印 p 对象的内容,下面两种方法都不可以,打出来的都是地址值//Object 类提供的 toString()方法总是返回该对象实现类的 类名“ + @ + hashCode ”的值System.out.println(p);System.out.println(p.toString());}}class Person{private String name;public Person(String name){this.name=name;}}重写 toString()方法,通过重写,就可以让系统在打印 Apple 对象时打印该对象的 自我描述 内容“ ”public class ToStringTest {public static void main(String[] args){Apple a=new Apple("red",100);//打印 Apple 对象System.out.println(a);}}class Apple{private String color;private double weight;//提供有参数的构造器public Apple(String color,double weight){this.color=color;this.weight=weight;}public String getColor(){return color;}public void setColor(String color){this.color=color;}public double getWeight(){return weight;}public void setWeigth(double weigth){this.weight=weight;}//重写 toString()方法public String toString(){return color+","+weight;}}5.2.2 ==和 equals 方法Java 中测试两个变量是否相等有两种方式,一种是利用==运算符,一种是利用 equals()方法。当使用==来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就将返回 true.对于两个引用类型变量,只有他们指向同一个对象时,==判断才会返回 true。==不可用于比较类型上没有父子关系的两个对象。public class EqualTest {public static void main(String[] args){int it=65;float fl=65.0f;System.out.println("65 和 65.0 是否相等?"+(it==fl)); //truechar ch='A';System.out.println("65 和 A 是否相等?"+(it==ch)); //trueString str1=new String("hello");String str2=new String("hello");System.out.println("str1 和 str2 是否相等?"+(str1==str2)); //falseSystem.out.println("str1 是否 equals str2?"+(str1.equals(str2))); //true}}当 Java 程序直接使用形如”hello”的字符串直接量(包括可以在编译时就计算出来的字符串值)时,JVM 将会使用常量池来管理这些字符串;当使用 new String("hello”)时,JVM 会先使用常量池来管理“hello”直接量,再调用 String 类的构造器来创建一个新的 String 对象,新创建的 String 对象被保存在堆内存中。换句话说,newString(“hello”)一共产生了两个字符串对象。public class StringCompareTest {public static void main(String[] args){//s1 直接引用常量池中的 疯狂“ java”String s1="疯狂 java";String s2="疯狂";String s3="java";//s4 s5 后面的字符串值可以在编译时就确定下来,它们都直接引用常量池中的 疯狂“ java”String s4="疯狂"+"java";String s5="疯"+"狂"+"java";//s6 后面的字符串值不能在编译时就确定下来String s6=s2+s3;//s7 引用堆内存中新创建的 String 对象String s7=new String("疯狂 java");System.out.println(s1==s4); //trueSystem.out.println(s1==s5); //trueSystem.out.println(s1==s6); //falseSystem.out.println(s1==s7); //false}}JVM 常量池保证相同的字符串直接量只有一个,不会产生多个副本。String 已经重写了 Object 的 equals()方法,String 的 equals()方法判断两个字符串相等的标准是:只要两个字符串所包含的字符序列相同,通过 equals()比较将返回 true,否则返回 false类成员不能访问实例成员如果一个类始终只能创建一个实例,则这个类被称为单例类public class SingletonTest {public static void main(String[] args){//创建 Singleton 对象不能通过构造器,只能通过 getInstance 方法得到实例Singleton s1=Singleton.getInstance();Singleton s2=Singleton.getInstance();System.out.println(s1==s2);}}class Singleton{//使用一个类变量来缓存曾经创建的实例private static Singleton instance;//对构造器使用 private 修饰,隐藏该构造器private Singleton(){}//提供一个静态方法,用于返回 Singleton 实例//该方法可以加入自定义控制,保证只产生一个 Singleton 对象public static Singleton getInstance(){//如果 Instance 为 Null,,则表明还不曾创建 singleton 对象//如果 intstance 不为 null,则表明已经创建了 Singleton 对象,将不会重新创建新的实例if(instance==null){instance=new Singleton();}return instance;}5.4 final 修饰符Final 修饰的变量不可被改变,一旦获得了初始值,该 final 变量的值就不能被重新赋值。因此 java 语法规定:final 修饰的成员变量必须由程序员显式的指定初始值。Final 修饰的类变量、实例变量能指定初始值的地方如下:类变量:必须在静态初始化块中指定初始值或声明该类型变量时指定初始值,而且只能在两个地方的其中之一指定实例变量:必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定。实例变量不能在静态初始化块中指定初始值,因为静态初始化块时静态成员,不可访问实例变量 非静态成员;类——变量不能在普通初始化块中指定初始值,因为类变量在类初始化阶段已经被初始化了,普通初始化块不能对其重新赋值。public class FinalVariableTest {//定义成员变量时指定默认值,合法final int a=6;//下面这三个变量将在构造器或初始化块中指定初始值final String str;final int c;final static double d;//ch 既没有指定默认值,有没有在初始化块、构造器中指定初始值// final char ch;//初始化块,对没有指定默认值的实例变量指定初始值{//在初始化块中为实例变量指定初始值,合法str="hello";//定义 a 实例变量时,已经指定了默认值,不能重新为 a 赋值// a=9;}static{//在静态初始化块中为类变量指定初始值,合法d=5.6;}public FinalVariableTest(){//str 在初始化块中已定义初始值,不可重新赋值// str="java";//构造器,可对既没有指定默认值,又没有在初始化块中指定初始值的实例变量指定初始值c=5;}public void changeFinal(){//普通方法不能为 final 修饰的成员变量赋值// d=1.2;//不能在普通方法中为 final 成员变量指定初始值// ch='a';}public static void main(String[] args){FinalVariableTest ft=new FinalVariableTest();System.out.println(ft.a);System.out.println(ft.c);System.out.println(ft.d);}}Final 局部变量系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化。因此 final 修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。如果 final 修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该final 变量赋初始值,但只能一次,不能重复赋值。当使用 final 修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本列表变量不能改变。但对于引用类型变量而言,它保存的仅仅是一个引用,final 只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以改变。public class FinalReferenceTest {public static void main(String[] args){//final 修饰数组变量,iArr 是一个引用变量final int[] iArr={5,6,12,9};System.out.println(Arrays.toString(iArr));//对数组元素排序,合法Arrays.sort(iArr);System.out.println(Arrays.toString(iArr));//对数组元素赋值,合法iArr[2]=-8;System.out.println(Arrays.toString(iArr));//对 iArr 重新赋值,非法// iArr=null;//final 修饰 Person 变量,p 是一个引用变量final Person p=new Person(45);//改变 p 对象的 age 实例变量,合法p.setAge(23);System.out.println(p.getAge());//对 p 重新赋值,非法// p=null;}}class Person{private int age;public Person(){}//有参数的构造器public Person(int age){this.age=age;}public void setAge(int age){this.age=age;}public int getAge(){return age;}}可执行 宏替换 的“ ” final 变量对于一个 final 变量来说,不管它是类变量、实例变量,还是局部变量,只要该变量满足三个条件,这个 final 变量就不再是一个变量,而是相当于一个直接量1)使用 final 修饰符修饰2)在定义该 final 变量时指定了初始值3)该初始值可以在编译时就被确定下来如果被赋的表达式只是基本的算术表达式或字符串连接运算,没有访问普通变量,调用方法,java 编译器同样会将这种 final 变量当成 宏变量 处理。“ ”public class FinalReplaceTest {public static void main(String[] args){//下面定义了 4 个 final 宏变量,因为编译器在编译时就可以确定final int a=5+2;final double b=1.2/3;final String str="疯狂"+"java";final String book="疯狂 java 讲义:"+99.0;//下面的 book2 变量的值因为调用了方法,所以无法在编译时被确定下来final String book2="疯狂 java 讲义:"+String.valueOf(99.0);System.out.println(book=="疯狂 Java 讲义:99.0"); //相等System.out.println(book2=="疯狂 java 讲义:99.0"); //不相等}}Java 会使用常量池来管理曾经用过的字符串直接量,例如执行 String a=”java”,语句之后,常量池中就会缓存一个字符串“Java”;如果程序再执行 String b=”java”,系统将会让 b 直接指向常量池中的“java”字符串,因此a==b 将会返回 true.public class StringJoinTest {public static void main(String[] args){String s1="疯狂 java";//s2 变量引用的字符串可以在编译时就确定下来,因此 s2 的直接引用常量池中已有的 疯狂“ java"字符串String s2="疯狂"+"java";System.out.println(s1==s2);String str1="疯狂";String str2="java";//str3 由 str1 和 str2 进行连接运算后得到的。由于 str1 和 str2 只是两个普通变量,编译器不会执行 宏替“换 ,因而不能在”// 编译时确定 s3 的值,也就无法让 s3 指定字符串池中缓存的 疯狂“ Java”String s3=str1+str2;System.out.println(s1==s3);//只要让编译器对 str1 和 str2 两个变量执行 宏替换 ,这样编译器即可在编译阶段就确定“ ” s3 的值,就会让s3 指向字符串池//中缓存的 疯狂“ java”。也就是,只要将 str1 和 str2 使用 final 修饰即可}}Final 方法Final 修饰的方法不可被重写,但是可以重载Final 类Final 修饰的类不可以有子类。因而为了保证某个类不可被继承,则可以使用 final 修饰这个类。5.5 抽象类抽象方法和抽象类必须使用 abstract 修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。抽象方法和抽象类的规则如下:1)抽象类必须使用 abstract 修饰符来修饰,抽象方法也必须使用 abstract 修饰符来修饰,抽象方法不能有方法体。2)抽象类不能被实例化,无法使用 new 关键字来调用抽象类的构造器创建抽象类的实例。即使抽象类里不包含抽象方法,这个抽象类也不能创建实例。3)抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其他子类调用。4)含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象父类,但没有完全实现父类包含的抽象方法;或实现了一个接口,但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。抽象类:多了一个能力,抽象类可以包含抽象方法;失去了一个能力,抽象类不能用于创建实例。定义抽象方法只需在普通方法上增加 abstract 修饰符,并把普通方法的方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号即可。定义抽象类只需在普通类上增加 abstract 修饰符即可。/*** Created by AIwen on 2017/5/19.*/public abstract class Shape {{System.out.println("执行 shape 的初始化块...");}private String color;//定义一个计算周长的抽象方法public abstract double calPerimeter();//定义一个返回形状的抽象方法public abstract String getType();//定义 Shape 的构造器,该构造器并不是用于创建 Shape 对象,而是用于被子类调用public Shape(){}public Shape(String color){System.out.println("执行 Shape 构造器");this.color=color;}public void setColor(String color){this.color=color;}public String getColor(){return color;}}public class Triangle extends Shape{private double a;private double b;private double c;public Triangle(String color,double a,double b,double c){super(color);this.setSides(a,b,c);}public void setSides(double a,double b,double c){if(a>=b+c||b>=a+c||c>=a+b){System.out.println("三角形两边之和必须大于第三边");return;}this.a=a;this.b=b;this.c=c;}public double calPerimeter(){return a+b+c;}public String getType(){return "三角形";}}public class Circle extends Shape{private double radius;public Circle(String color,double radius){super(color);this.radius=radius;}public void setRadius(double radius){this.radius=radius;}public double calPerimeter(){return 2*Math.PI*radius;}public String getType(){return getColor()+"圆形";}public static void main(String[] args){Shape s1=new Triangle("黑色",3,4,5);Shape s2=new Circle("黄色",3);System.out.println(s1.getType());System.out.println(s1.calPerimeter());System.out.println(s2.getType());System.out.println(s2.calPerimeter());}}当使用 abstract 修饰类时,表明这个类只能被继承;当使用 abstract 修饰方法时,表明这个方法必须由子类提供实现(即重写)。而 final 修饰的类不能被继承,final 修饰的方法不能被重写。因此 final 和 abstract 永远不能同时使用。Abstract 不能修饰变量,也不能用于修饰构造器。Static 和 abstract 不能同时修饰某个方法,但它们可以同时修饰内部类。Private 和 abstract 不能同时修饰方法抽象类不能创建实例,只能当成父类来被继承。抽象类体现的就是一种模板模式的设计。如果编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,这就是一种模板模式,模板模式也是十分常见且简单的设计模式之一。public abstract class SpeedMeter {private double turnRate;public SpeedMeter(){}//把返回车轮半径的方法定义成抽象方法public abstract double getRadius();public void setTurnRate(double turnRate){this.turnRate=turnRate;}public double getSpeed(){return java.lang.Math.PI*2*getRadius()*turnRate;}}public class CarSpeedMeter extends SpeedMeter{public double getRadius(){return 0.28;}public static void main(String[] args){CarSpeedMeter csm=new CarSpeedMeter();csm.setTurnRate(15);System.out.println(csm.getSpeed());}}5.6 java8 改进的接口接口里不能包含普通方法,接口里的所有方法都是抽象方法。Java8 对接口进行了改进,允许在接口中定义默认方法,默认方法可以提供方法实现。接口定义了某一批类所需要遵守的规范,接口不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可满足实际需要。接口是从多个相似类中抽象出来的规范,接口不提供任何实现。定义接口使用 interface 关键字1)修饰符可以是 public 或者省略,如果省略了 public 访问控制符,则默认采用包访问控制符,即只有在相同包结构下才可以访问该接口。2)接口名应与类名采用相同的命名规则,接口名通常能够使用形容词。3)一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。由于接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义。接口里可以包含成员变量(只能是静态常量)、方法(只能是抽象实例方法、类方法或默认方法)、内部类(包括内部接口、枚举)定义。接口里定义的是多个类共同的公共行为规范,因此接口里的所有成员,包括常量、方法、内部类和内部枚举都是public 访问权限。定义接口成员时,可以省略访问控制修饰符,如果指定访问控制修饰符,则只能使用 public 访问控制修饰符。对于接口里的定义的静态常量而言,它们是接口相关的,因此系统会自动为这些成员变量增加 static 和 final 两个修饰符。也就是说,在接口中定义成员变量时,不管是否使用 public static final 修饰符,接口里的成员变量总是使用这三个修饰符来修饰。而且接口里没有构造器和初始化块,因此接口里定义的成员变量只能在定义时指定默认值。接口里定义的方法只能是抽象方法、类方法或默认方法,因此如果不是定义默认方法,系统将自动为普通方法增加abstract 修饰符;定义接口里的普通方法时不管是否使用 public abstract 修饰符,接口里的普通方法总是使用public abstract 来修饰。接口里的普通方法不能有方法实现(方法体);但类方法、默认方法都必须由方法实现(方法体).接口里定义的内部类、内部接口、内部枚举默认都采用 public static 两个修饰符public interface Output {//接口里定义的成员变量只能是常量int MAX_CACHE_LIN=50;//接口里定义的普通方法只能是 public 的抽象方法void out();void getData(String msg);//接口中定义的默认方法,需要使用 defualt 修饰default void print(String... msgs){for(String msg:msgs){System.out.println(msg);}}default void test(){System.out.println("默认的 test()方法");}//在接口中定义类方法,需要使用 static 修饰static String staticTest() {return "接口中的类方法";}}Java8 允许在接口中定义默认方法,默认方法必须使用 default 修饰,该方法不能使用 static 修饰,无论程序是否指定,默认方法总是使用 public 修饰。由于默认方法不能使用 static 修饰,因此不能直接使用接口来调用默认方法,需要使用接口的实现类的实例来调用这些默认方法Java8 允许在接口中定义类方法,类方法必须使用 static 修饰,该方法不能使用 default 修饰。无论程序是否指定,类方法总是使用 public 修饰。类方法可以直接使用接口来调用。接口中的成员变量默认是使用 public static final 修饰,因此即使另一个类处于不同包下,也可以通过接口来访问接口里的成员变量。从某个角度来看,接口可被当成一个特殊的类,因此一个 java 源文件里最多只能有一个 Public 接口,如果一个 java源文件里定义了一个 public 接口,则该源文件的主文件名必须与该接口名相同。接口的继承:接口的继承和类继承不一样,接口完全支持多继承,即一个接口可以有多个直接父接口。和类继承相似,子接口扩展某个父接口,将会获得父接口里定义的所有抽象方法、常量。一个接口继承多个父接口,多个父接口排在 extends关键字之后,多个父接口之间以英文逗号隔开。public class InterfaceExtendsTest {public static void main(String[] args){System.out.println(interfaceC.PROP_A);System.out.println(interfaceC.PROP_B);System.out.println(interfaceC.PROP_C);}}interface interfaceA{int PROP_A=5;void testA();}interface interfaceB{int PROP_B=6;void testB();}interface interfaceC extends interfaceA,interfaceB{int PROP_C=7;void testC();}一个类可以实现一个或者多个接口,继承使用 extends 关键字,实现则使用 implements 关键字。一个类可以继承一个父类,并同时实现多个接口,implements 部分必须放在 extends 部分之后。一个类实现类一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义成抽象类。接口和抽象类相同点:接口和抽象类都不能实例化,都包含抽象方法。不同点:1)接口里只能包含抽象方法和默认方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法2)接口里不能定义静态方法;抽象类里可以定义静态方法3)接口里只能定义静态常量,不能定义普通成员变量;抽象类里既可以定义普通成员变量,也可以定义静态常量4)接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。5)接口里不能包含初始化块;但抽象类则完全可以包含初始化块。6)一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补java 单继承的不足。5.7 内部类1)内部类提供了更好的封装,把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类。2)内部类成员可以直接访问外部类的私有数据,因为内部类被当成其他外部类成员,同一个类的成员之间可以互相访问。但外部类不能访问内部类的实现细节,例如内部类的成员变量。3)匿名内部类适合用于创建那些仅需要一次使用的类。内部类除了需要定义在其他类里面之外,还存在如下两点:1)内部类比外部类可以多使用三个修饰符:private、protected、static—外部类不可以使用这三个修饰符。2)非静态内部类不能拥有静态成员在非静态内部类中可以直接访问外部类的 private 的实例变量:public class Cow {private double weight;public Cow(){ }public Cow(double weigth){this.weight=weight;}private class CowLeg{//非静态内部类的两个实例变量private double length;private String color;public CowLeg(){ }//非静态内部类的两个重载的构造器public CowLeg(double length,String color){this.length=length;this.color=color;}public void setLength(double length){this.length=length;}public double getLength(){return length;}public void setColor(String color){this.color=color;}public String getClor(){return color;}//非静态内部类的实例方法public void info(){System.out.println("当前牛的颜色:"+color+"高:"+length);//直接访问外部类的 private 修饰的成员变量System.out.println("本牛腿所在奶牛重:"+weight);}}public void test(){CowLeg cl=new CowLeg(1.12,"黑白相间");cl.info();}public static void main(String[] args){Cow cow=new Cow(378.9);cow.test();}}如果外部类成员变量、内部类成员与内部类里方法的局部变量同名,则可通过使用 this、外部类类名.this 作为限定来区分:public class DiscernVariable {private String prop="外部类的实例变量";private class InClass{private String prop="内部类的实例变量";public void info(){String prop="局部变量";// System.out.println("外部类的实例变量:"+new DiscernVariable().prop);//通过外部类类名.this.varName 访问外部类实例变量System.out.println("外部类的实例变量:"+DiscernVariable.this.prop);//通过 this.varName 访问内部类实例的变量System.out.println("局部变量的值:"+prop);}}public void test(){InClass in=new InClass();in.info();}public static void main(String[] args){new DiscernVariable().test();}}非静态内部类的成员可以访问外部类的 private 成员,但反过来就不成立了。非静态内部类的成员只在非静态内部类范围内是可知的,并不能被外部类直接使用。如果外部类需要访问非静态内部类的成员,则必须显示创建非静态内部类对象来调用访问其实例成员。public class outer {private int outProp=9;class Inner{private int inprop=5;public void acessOuterProp(){//非静态内部类可以直接访问外部类的 private 成员变量System.out.println("外部类的 outProp 值:"+outProp);}}public void accessInnerProp(){//外部类不能直接访问非静态内部类的实例变量// System.out.println("内部类的 inprop:"+inprop);//如需访问内部类的实例变量,必须显示创建内部类对象System.out.println("内部类的 inprop:"+new Inner().inprop);}public static void main(String [] args){outer out=new outer();out.accessInnerProp();}}5.7.2 静态内部类如果使用 static 修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。静态内部类可以包含静态成员,也可以包含非静态成员。静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。public class AccessStaticInnerClass {static class StaticInnerClass{private static int propl=5;private int prop2=9;}public void accessInnerProp(){//通过类名访问静态内部类的类成员System.out.println(StaticInnerClass.propl);//通过实例访问静态内部类的实例变量System.out.println(new StaticInnerClass().prop2);}public static void main(String[] args){AccessStaticInnerClass asi=new AccessStaticInnerClass();asi.accessInnerProp();}}接口内部类只能是静态内部类。接口里定义的内部类默认使用 public static 修饰。5.7.3 使用内部类在外部类以外的地方使用内部类,内部类完整的类名应该是 OuterClass.InnerClass;创建非静态内部类对象之前,必须先创建其外部类对象。OuterInstance.new InnerConstructor();public class CreateInnerInstance {public static void main(String[] args){//非静态内部类的构造器必须使用外部类对象来调用Out.In in=new Out().new In("测试信息");}}class Out{class In{public In(String msg){System.out.println(msg);}}}在外部类以外使用静态内部类:因为静态内部类是外部类类相关的,因此创建静态内部类对象时无须创建外部类对象。在外部类以外的地方创建静态内部类实例的语法如下:new OuterClass.InnerConstructor();public class CreateStaticInnerInstance {public static void main(String[] args){StaticOut.StaticIn in=new StaticOut.StaticIn();}}class StaticOut{static class StaticIn{public StaticIn(){System.out.println("静态内部类的构造器");}}}不管是静态内部类还是非静态内部类,它们声明变量的语法完全一样。区别是在创建内部类对象,静态内部类只需使用外部类即可调用构造器,而非静态内部类必须使用外部类对象来调用构造器。匿名内部类:匿名内部类必须继承一个父类或实现一个接口,但最多只能继承一个父类,或实现一个接口。匿名内部类不能是抽象类;匿名内部类不能定义构造器。最常用的创建匿名内部类的方式是需要创建某个接口类型的对象:public class AnonymousTest {public void test(Product p){System.out.println("购买了一个"+p.getName()+",花掉了"+p.getPrice());}public static void main(String[] args){AnonymousTest ta=new AnonymousTest();//调用一个 test()方法时,需要传入一个 Product 参数,此处传入其匿名内部类的实例ta.test(new Product(){public double getPrice(){return 567.8;}public String getName(){return "AGP 显卡";}});}}interface Product{public double getPrice();public String getName();}Test()方法需要传入一个 Product 对象作为参数,但 product 只是一个接口,无法直接创建对象。因此此处考虑创建一个 Product 接口实现类的对象传入该方法 如果这个—— Product 接口实现类需要重复使用,则应该将该实现类定义成一个独立类;如果这个 Product 接口实现类只需一次使用,则可以定义一个匿名内部类。定义匿名内部类无须 class 关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。5.9 枚举类一个类的对象是有限而且固定的,在 java 里被称为枚举类。枚举类和其他类的区别:1)使用 enum 定义的枚举类默认继承了 java.lang.Enum 类,而不是默认继承的 Object 类。2)使用 enum 定义、非抽象的枚举类默认会使用 final 修饰,因此枚举类不能派生子类。3)枚举类的构造器只能使用 private 访问控制符。默认和指定都是 private4)枚举类的所有实例必须在枚举类的第一行显式列出,系统会自动添加 public static final 修饰public enum SeasonEnum {SPRING,SUMMER,FALL,WINTER;}public class EnumTest {public void judge(SeasonEnum s){//switch 语句里的表达式可以是枚举值switch(s){case SPRING:System.out.println("穿暖花开,正好踏青");break;case SUMMER:System.out.println("夏日炎炎,适合游泳");break;case FALL:System.out.println("秋高气爽,进补及时");break;case WINTER:System.out.println("冬日雪飘,围炉赏雪");break;}}public static void main(String[] args){//枚举类默认有一个 values()方法,返回该枚举类的所有实例for(SeasonEnum s:SeasonEnum.values()){System.out.println(s);}//使用枚举类实例时,可通过 EnumClass.variable 形式来访问new EnumTest().judge(SeasonEnum.SPRING);}}枚举类的实例只能是枚举值,而不是随意的通过 new 来创建枚举类对象String StringBuffer StringBuilder 类String 类是不可变类,即一旦一个 String 对象被创建后,包含在这个对象中的字符序列是不可改变的,直到这个对象被销毁。StringBuffer 对象则代表一个字符序列可变的字符串,当一个 StringBuffer 被创建以后,通过 StringBuffer 提供的append()、insert()、reverse()等方法可以改变这个字符串对象的字符序列。一旦通过 StringBuffer 生成了最终想要的字符串,就可以调用它的 toString()方法将其装换为一个 String 对象。StringBuffer 是线程安全的,而 StringBuilder 则没有实现线程安全功能,所以性能略高。因此通常情况下,如果需要创建一个内容可变的字符串对象,则应该优先考虑使用 StringBuilder 类。

Created by AIwen on 2017/5/14.java是面向对象的程序设计语言;
不属于该类的单个实例,因此通过把static修饰的成员变量和方法被
类作为调用者。也就是说java中看起来某些方法可以被独立执行,但
olv.test("aa","bb");//将调用第一个test方法olv.test("aa");//
还剩 27页未读,点此继续全文在线阅读

免费下载java基础知识点总结到电脑,使用更方便!

本文推荐: java基础知识点总结.docx全文阅读下载  关键词: 基础   基础知识   知识   知识点   总结   java  
学文库温馨提示:文档由用户自行上传分享,文档预览可能有差异,下载后仅供学习交流,未经上传用户书面授权,请勿作他用。 文档下载资源交流QQ群:317981604
< / 31>

QQ|小黑屋|网站声明|网站地图|学文库 ( 冀ICP备06006432号 )

GMT+8, 2020-7-7 03:28 , Processed in 0.721948 second(s), 5 queries , Gzip On, Redis On.

Powered by 学文库 1.0

Copyright © 2019-2020, 学文库

返回顶部