Java核心技术卷感悟:第五章 继承
本章将学习面向对象程序设计的另外一个基本概念: 继承(inheritance)。利用继承,人们可以基于已存在的类构造一个新类。继承已存在的类就 是复用(继承)这些类的方法和域。
1. 关键字 extends 表示继承(public class Manager extends Employee)。关键字 extends 表明正在构造的新类派生于一个已存在的类。 已存在的类称为超类 ( superclass)、 基类( base class) 或父类(parent class); 新类称为子类(subclass、) 派生类 ( derived class) 或孩子类(child class)
2. 在通过扩展超类定义子类的时候,仅需要指出子类与超类的不同之处。因此在设计类的时候,应该将通用的方法放在超类中, 而将具有特殊用途的方法放在子类中
3. 有些人认为 super 与 this 引用是类似的概念, 实际上,这样比较并不太恰当。这是 因为 super 不是一个对象的引用, 不能将 super 赋给另一个对象变量, 它只是一个指示编 译器调用超类方法的特殊关键字。
关键字 this 有两个用途: 一是引用隐式参数,二是调用该类其他的构 造器 , 同样,super 关键字也有两个用途:一是调用超类的方法,二是调用超类的构造器。
4. 由于 子类的构造器不能访问超 类的私有域, 所以必须利用 超 类 的构造器对这部分私有域进行初始化,我们可以通过 super 实现对超类构造器的调用。使用 super 调用构造器的语句必须是子类构造器的第一条语句。
如果子类的构造器没有显式地调用超类的构造器, 则将自动地调用超类默认(没有参数 ) 的构造器。 如果超类没有不带参数的构造器, 并且在子类的构造器中又没有显式地调用超类 的其他构造器,则 Java 编译器将报告错误。
5. 一个对象变量(例如, 变量 e ) 可以指示多种实际类型的现象被称为多态( polymorphism)。 在运行时能够自动地选择调用哪个方法的现象称为动态绑定( dynamic binding。)
6. 有时候,可能希望阻止人们利用某个类定义子类。不允许扩展的类被称为 final 类。如果 在定义类的时候使用了 final 修饰符就表明这个类是 final 类。
类中的特定方法也可以被声明为 final。如果这样做,子类就不能覆盖这个方法( final 类中的所有方法自动地成为 final 方法 ) ,将方法声明为 final 主要目的是: 确保它们不会在子类中改变语义。
7. 对象引用的转换语法与数值表达式的类型转换类似, 仅 需要用一对圆括号将目标类名括起来,并放置在需要转换的对象引用之前就可以了,Manager boss = (Manager) staff[0];
将一个子类的引用赋给一个超类 变量, 编译器是允许的。但将一个超类的引用赋给一个子类变量, 必须进行强制类型转换, 这样 才能够通过编译时的检査。
总之,1、只能在继承层次内进行类型转换。2、在将超类转换成子类之前,应该使用 instanceof进行检查。(instanceof会检查变量的运行类型)
8. 如果自下而上在类的继承层次结构中上移,位于上层的类更具有通用性,甚至可能更加 抽象,祖先类更加通用, 人们只将它作为派生其他类的基类,而不作为想使 用的特定的实例类。
9. 包含一个或多个抽象方法的类本身必须被声明为抽象的,除了抽象方法之外,抽象类还可以包含具体数据和具体方法。抽象方法充当着占位的角色, 它们的具体实现在子类中。类即使不含抽象方法,也可以将类声明为抽象类,而抽象类不能被实例化。
需要注意, 可以定义一个抽象类的对象变量, 但是它只能引用非抽象子类的对象,这是运用到了多态的知识。
10. Java 用于控制可见性的 4 个访问修饰符:1 ) 仅对本类可见 private。2 ) 对所有类可见 public。3 ) 对本包和所有子类可见 protected。4 ) 对本包可见—默认(很遗憾,) 不需要修饰符。
11. Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的,如果没有明确地指出超类,Object 就被认为是这个类的超类。
在 Java 中,只有基本类型 ( primitive types) 不是对象, 例如,数值、 字符和布尔类型的 值都不是对象。 所有的数组类型,不管是对象数组还是基本类型的数组都扩展了 Object 类。
12. Object 类中的 equals 方法用于检测一个对象是否等于另外一个对象,在 Object 类中,这 个方法将判断两个对象是否具有相同的引用,如果两个对象具有相同的引用, 它们一定是相 等的。然而,对于多数类来说, 这种判断 并没有什么意义。所以我们经常在子类中,重写基类的equals。
13. 在 Object 中还有一个重要的方法, 就是 toString方法, 它用于返回表示对象值的字符 串。当然,设计子类的程序员也应该定义自己的 toString 方法,并将子类域的描述添加进去。 强烈建议为自定义的每一个类增加 toString 方法。这样做不仅自己受益, 而且所 有使用这个类的程序员也会从这个日志记录支持中受益匪浅
14. ArrayList 是一个采用类型参数( type parameter ) 的泛型类( generic class)。为了指定数 组列表保存的元素对象类型,需要用一对尖括号将类名括起来加在后面, 例如,ArrayList类型,ArrayList<Employee> staff = new ArrayList();这被称为“ 菱形” 语法,因为空尖括号<>就像是一个菱形.
数组列表自动扩展容量的便利增加了访问元素语法的复 杂程度。 其原因是 ArrayList 类并不是 Java 程序设计语言的一部分,它只是一个由某些人编 写且被放在标准库中的一个实用类。
15. 有时, 需要将 int 这样的基本类型转换为对象, 所有的基本类型都冇一个与之对应的类。例如,Integer 类对应基本类型 int。通常, 这些类称为包装类 ( wrapper ) 。
Integer、Long、Float、Double、Short、Byte、Character 、 Boolean (前 6 个类派生于公共的超类 Number)。
继承的设计技巧:
1. 将公共操作和域放在超类
2. 不要使用受保护的域
3. 使用继承实现“ is-a” 关系
4. 除非所有继承的方法都有意义,否则不要使用继承
5. 在覆盖方法时,不要改变预期的行为
6. 使用多态, 而非类型信息
