一、学习内容摘要
第二章:
1、面向对象的三大特性:封装,继承,多态。
2、多态的三要素:继承,重写,父类引用指向子类对象
3、方法的重写和重载
4、接口的定义和实现,与抽象类的不同
5、构造方法及new对象的实现细节
6、静态成员与实例成员的区别
7、耦合和内聚
第三章
1、基本赋值
2、使用未初始化或为赋值的变量或数组元素
3、数组声明、构建和初始化,main函数中的args变元
4、包装器的引入和其中的方法
5、装箱、加宽、var-arg和重载
垃圾收集
二、知识点总结
1、重写与重载:重写是基于继承实现的,只能对继承来的实例方法进行重写。重写方法必须与原方法有相同的方法名、变元列表,返回类型必须与原方法的返回类型相同或是其子类型,访问修饰符不能比原方法严格。重写方法不能抛出比原方法抛出的更新更广异常,因为异常声明是在编译时,要确保原方法声明的异常能够捕获重写方法的异常。还要注意当原方法声明异常Exception,而重写方法未声明异常,使用指向子类对象的父类引用调用该方法时要声明Exception。子类对父类未继承来的成员只能有重新定义而不存在重写。
而重载是基于对原方法所传参数数量、返回类型等不满足实现的。重载必须与原方法具有相同的方法名,必须与方法有不同的变元列表。而访问修饰符和返回类型可随意改变。注意long和int、short就可做不同的变元列表,默认整数是int型,要传给long就要在末尾加上L,要传给short就要进行显示强制装换(short)。
注意事项:尽管静态方法可以继承,但不能重写,只能重新定义,即方法体里的代码实现不同。因为静态方法的调用只看引用类型,即在编译时就确定了。而实例方法的调用在编译时确定父类是否有该方法,在实际调用时,JVM会智能识别调用的实际对象。所谈到重写都是针对能够继承来的实例方法。实例变量不存在重写,改变子类继承来的实例变量并不会影响到父类相应实例变量的值。静态=类,非静态=实例。
Interface中的方法全都是public的,因此即使它没有显示表明,实现接口的所有方法都应该显示标为public。
2、接口与抽象类的不同:接口的访问修饰符只有默认的和public,接口中的所有方法都是public abstract,所有成员都是public static final,接口中没有构造方法。而抽象类与一般的类相似,可以有抽象方法,有构造方法但不能被实例化,即不能new对象。而且有抽象方法的类一定要被标识为抽象类。
3、构造方法:每个类中都有隐式的无参构造方法,而若重载有参构造方法,那么编译器就不会隐式地实现无参的构造方法,因此要注意子类构造方法中第一行中隐式的super()语句调用是否有效。构造方法不存在重写。构造函数中调用本类的构造函数要用this,调用父类的构造函数要用super,而不能直接用方法名。构造函数一定不能有返回类型。构造函数能使用任何访问修饰符,但其使用default和protected效果相同。构造函数中只有在超类构造函数调用完成后才能访问实例成员。对this和super的调用不能位于同一个构造内,构造函数只能有其一,因为二者都必须位于构造函数的第一行。
B:New对象的实现细节:如new sub()
1、在堆中开辟空间,加载类和其静态成员
2、调用静态代码块对类进行初始化,只在初次加载类时调用一次。
3、加载实例成员并默认初始化
4、调用构造函数中的super()语句直到Object类
5、对成员进行显示初始化,如int age=5;
6、调用构造代码块对对象进行初始化
7、执行构造函数中余下的代码
4、静态成员和实例成员的区别:
A、变量上的区别:静态变量即类变量只有一份副本,类的所有对象共享该副本;而实例变量可有多个副本,不同的对象可以有不同的值,并且某个对象改变其实例变量的值不会影响到其他对象中对应的实例变量的值。
B、方法上的区别:静态方法直接通过类名调用,即使你使用类名调用,在编译眼里看到的是类名调用。静态方法中不能直接调用非静态方法和非静态变量,但可以通过创建对象调用。使用静态方法实现的行为不收任何实例变量状态的影响,因为静态优先于实例。
5、耦合和内聚
耦合是指类和类之间的联系程度如果一个类拥有多个类的实例,则称这个类是紧耦合,即与别的类紧密联系。内聚是指一个类的功能单一的程度,如工厂类的功能是生产对象,称高内聚。高内聚有利于代码的复用性,松耦合有利于代码的可维护性。
第三章
1、基本类型的使用:整数隐含文int,整数表达式总是会导致一个int大小的结果,而永远不会导致更小的结果。浮点数隐含为double,收缩浮点型为整型会截取小数部分。组合赋值如+=执行自动强制转换。引用变量可以引用所声明类型的子类型,但不能引用其父类。如果知道对象的实际类型则可强转,强转时编译器不知对象的实际类型因此都会编译成功,而运行时转换失败会抛异常。
2、使用未初始化和未赋值的变量或数组元素。
A、对于变量:实例变量会在调用构造函数时默认初始化和赋值(若声明变量时赋值了的话),对于局部变量无论是基本类型还是引用类型,必须在使用它之前对它进行初始化,否则编译报错。引用变量未初始化和初始化为null并不一样:初始化为null后可以使用并在其上调用点运算符,即编译可以通过。
B、对于数组:当实例化一个对象数组时,该数组内的对象不会被自动实例化,但都会得到默认值null。而当实例化基本类型的数组时数组元素也都会得到相应的默认值。(无论是实例数组还是局部数组)
实例数组会在调用构造函数时自动初始化为null(数组名而非数组内元素),局部数组则必须在使用前初始化。
3、数组声明,赋值
子类数组对象能够传参给父类数组引用
任何数组本身就是一个对象,Object都是其父类。因此任何一个数组都可当做实参传给形参Object。
不能在声明数组时包含数组大小,因为只有在实例化时JVM才会分配空间,因此在new构建数组时,必须包含其大小。
对象数组中的元素不会被自动创建(只在实例化数组时会被赋默认值为null),即使基本数组元素
会被赋予一个默认值。
每个数组都有一个int属性值length,其值为在实例化数组时包含的大小。
多维数组中的维数可以有不同的大小
当讲一个数组赋予以前声明的数组引用时,正在赋值的数组必须与被赋值的引具有相同的维数
4、使用包装器
包装器具有两个功能:包装基本类型,使它们能够像对象一样被处理;为基本类型提供实用的工具方法(通常是转换,如将字符串中的数字转为基本类型)。
三个最重要的方法:
A、非静态xxxValue(),不带任何变元,返回对应的基本类型xxx
B、静态parseXxx(),带String变元,重载的第二个变元是一个int,表示String中的数字是以int为基数的,返回基本类型,基数是10
C、静态valueOf(),带String变元,同样有个基数的重载,返回对应的包装器
BC若失败,会抛出NumberFormatEx
除了Character只能带char变元 即new Character(char),包装器构造函数能够带String或基本类型变
Boolean.parseBoolean(“tRue”);返回true 即不分大小写
对具有相同的较小值(通常小于127)的包装器对象使用==都返回true,而对具有相同值的任何包装器对象使用equals都返回true,因为其中重写的equal只比较包装器包装的数值
5、装箱,加宽,var-arg和重载
加宽优先于装箱,装箱优先与多元参数
基本值的加宽使用可能的“最小”方法变元
不能从一种包装器类型加宽到另一种包装器类型,而包装器类型都能加宽到Object类型
不能先加宽后装箱(int不能传给long),而允许先装箱后加宽(int——>Integer——>Object)
加宽优先于装箱,因为即使每个调用都要求某种转换,在选择较新的风格之前,编译器仍将优先选择较老的风格(装箱是后来引入的),以保持已经存在的代码更加健壮。
6、垃圾收集
垃圾收集有两种情况:
A、处于隔离岛中的对象,没有被栈中的处于活线程的引用变量引用
B、方法内创建的对象,在方法结束时没有返回被方法内创建对象的引用