专栏:《Java面向对象程序设计》学习笔记
第 5 章 类与对象
5.1 子类与父类
有新类继承一般类视频讲解的状态和行为,并根据需要增加新的状态和行为。
由继承得到的类称为子类,被继承的类称为父类(超类)。
Java 不支持多重继承(子类只能有一个父类)。
使用关键字 extends 来声明一个类的子类。
5.2 子类的继承性
详细可见 4.10 访问权限
5.3 子类对象的构造过程
当用子类的构造方法创建一个子类的对象时,子类的构造方法总是先调用父类的某个构造方法。
也就是说,如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类不带参数的构造方法。
5.4 成员变量的隐藏和方法重写
只要子类中声明的成员变量和父类中的成员变量同名,子类就隐藏了继承的成员变量(就是重新声明)。
子类对象可以调用从父类继承的方法操作隐藏的成员变量。
5.4.2 方法重写
子类通过重写( override )可以隐藏已继承的实例方法(方法重写也称为方法覆盖)。
方法重写是指在子类中定义一个方法,这个方法的类型和父类的方法的类型一致,或者是父类的方法的类型的子类型(所谓子类型,是指如果父类的方法的类型是“类”,那么允许子类的重写方法的类型是“子类”),并且这个方法的名字、参数个数、参数的类型和父类的方法完全相同。
子类通过方法的重写可以隐藏继承的方法,可以把父类的状态和行为改变为自身的状态和行为。
重写方法既可以操作继承的成员变量,也可以操作子类新声明的成员变量。
如果子类想使用被隐藏的方法,必须使用关键字 super。
重写的注意事项:重写父类的方法时,不可以降低方法的访问权限。
5.5 super 关键字
在子类中想使用被子类隐藏的成员变量或方法,可以使用关键字 super。
5.5.1 使用 super 调用父类的构造方法
super 必须是子类构造方法中的头一条语句。
需要注意的是,如果在子类的构造方法中,没有明显地写出 super 关键字来调用父类的某个构造方法,那么默认有:super(); 语句,即调用父类的不带参数的构造方法。
当在父类中定义多个构造方法时,应当包括一个不带参数的构造方法,以防子类省略 super 时出现错误。
5.5.2 使用 super 操作被隐藏的成员变量和方法
当 super 调用隐藏的方法时,该方法中出现的成员变量是指被隐藏的成员变量。
5.6 final 关键字
final 关键字可以修饰类、成员变量和方法中的局部变量。
5.6.1 final 类
Final 类不能被继承,即不能有子类
5.6.2 final 方法
如果用 final 修饰父类中的一个方法,那么这个方法不允许子类重写。
不允许子类隐藏可以继承的 final 方法(不许做任何篡改)。
5.6.3 常量
如果成员变量或局部变量被修饰为 final ,就是常量。
常量在声明时没有默认值,所以在声明常量时必须指定该常量的值,而且不能发生变化。
5.7 对象的上转型对象
假设 A 类是 B 类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中,例如:
A = a ;
a = new B() ;
或
A = a ;
B b = new B() ;
a = b ;
这时,称对象是对象 b 的上转型对象(例如说“老虎是哺乳动物”)。
对象的上转型对象的实体是子类负责创建的,但上转型对象会失去原对象的一些属性和功能。
- 上转型对象不能操作子类新增的成员变量(失掉了这部分属性),不能调用子类新增的方法(失掉了一些功能)。
- 上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类的重写方法。
注:
- 不要将父类创建的对象和子类对象的上转型对象混淆。
- 可以将对象的上转型对象强制转换到一个子类对象,这时,该子类对象又具备了子类的所有属性和功能。
- 不可以将父类创建的对象的引用赋给子类声明的对象(不能说“哺乳动物是老虎”)。
- 如果子类重写了父类的静态方法(方法),那么子类对象的上转型对象不能调用子类重写的静态方法,只能调用父类的静态方法。
(个人理解是,优先使用子类的成员变量和方法(除了子类新增的成员变量和新增的方法、子类重写了父类的静态方法外),之后才使用父类的成员变量和方法)
5.8 继承与多态
当一个类有很多子类,并且这些子类都重写了父类中的某个方法时,把子类创建的对象的引用放到一个父类的对象中,就得到了该对象的一个上转型对象。
这个上转型对象在调用这个方法时可能具有多种形态,因为不同的子类在重写父类的方法时可能产生不同的行为。
多态性是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。
5.9 abstract 类和方法
用关键字 abstract 修饰的类称为 abstract 类(抽象类)。
用关键字 abstract 修饰的方法称为 abstract 方法(抽象方法),对于 abstract方法,只允许声明,不允许实现,而且不允许使用 final 和 abstract 同时修饰一个方法。
5.9.1 abstract 类的特点与理解
和普通类(非 abstract 类)相比, abstract 类中可以有 abstract 方法(非 abstract 类中不可以有 abstract 方法),也可以有非 abstract 方法。
abstract 类中也可以没有 abstract 方法。
abstract 类不能用 new 运算符创建对象。
abstract 类的子类
如果一个非 abstract 类是 abstract 类的子类,它必须重写父类的 abstract 方法,即去掉abstract 方法的 abstract 修饰,并给出方法体。如果一个 abstract 类是 abstract 类的子类,它可以重写父类的 abstract 方法,也可以继承父类的 abstract 方法。
abstract 类的对象作上转型对象
可以使用 abstract 类声明对象,尽管不能使用 new 运算符创建该对象,但该对象可以成为其子类对象的上转型对象,那么该对象就可以调用子类重写的方法。
( 1) 抽象类可以抽象出重要的行为标准,该行为标准用抽象方法来表示。即抽象类封装了子类必须有的行为标准。
( 2 )抽象类声明的对象可以成为其子类的对象的上转型对象,调用子类重写的方法,即体现子类根据抽象类里的行为标准给出的具体行为。
抽象类的重要特点是,特别关心方法名字、类型以及参数,但不关心这些操作具体实现的细节,即不关心方法体。
5.9.2 abstract 类与多态
abstract 类只关心操作,不关心这些操作具体实现的细节。
使用多态进行程序设计的核心技术之一是使用上转型对象,即将 Abstract 类声明对象作为其子类的上转型对象,那么这个上转型对象就可以调用子类重写的方法。
5.10 接口
概念很多,且容易与其他的搞混淆,暂时先留着。
5.11 小结
- 继承是一种由己有的类创建新类的机制。利用继承可以先创建一个共有属性的一般类,再根据该一般类创建具有特殊属性的新类。
- 所谓子类继承父类的成员变量作为自己的一个成员变量,就像它们是在子类中直接声明一样,可以被子类中自己声明的任何实例方法操作。
- 所谓子类继承父类的方法作为子类中的一个方法,就像它们是在子类中直接声明一样,可以被子类中自己声明的任何实例方法调用。
- 多态是面向对象编程的又一重要特性。子类可以体现多态,即子类可以根据各自的需要重写父类的某个方法,子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为。接口也可以体现多态,即不同的类在实现同一接口时,可以给出不同的实现手段。
- 在使用多态设计程序时,要熟练地使用上转型对象或接口回调,以便体现程序设计所提倡的“开-闭”原则。