第五章
主要内容
-
子类与父类
-
继承是一种由已有的类创建新类的机制。
-
利用继承,我们可以先创建一个共有属性的一般类,根据该一般类再创建具有特殊属性的新类,新类继承一般类的状态和行为,并根据需要增加它自己的新的状态和行为。
-
由继承而得到的类称为子类,被继承的类称为父类(超类)。
-
Java
不支持多重继承(子类只能有一个父类)。 -
声明子类
- 使用关键字
extends
来定义一个类的子类class 子类名 extends 父类名 { … } 例如: class Student extends People { … }
- 说明:
- 把
Student
类定义为People
类的子类、 People
类是Student
类的父类
- 把
- 使用关键字
-
类的树形结构
Java
的类按继承关系形成树形结构这个树形结构中,根节点是Object
类(Object
是java.lang
包中的类),即Object
是所有类的祖先类。- 除了
Object
类,每个类都有且仅有一个父类,一个类可以有多个或零个子类。 - 如果一个类(除了
Object
类)的声明中没有使用extends
关键字,这个类被系统默认为是Object
的子类,即类声明class A
与class A extends Object
是等同的。
-
-
子类的继承性
-
类可以有两种重要的成员:
- 成员变量
- 方法。
-
子类的成员中有一部分是子类自己声明定义的,另一部分是从它的父类继承的。
-
所谓子类继承父类的成员变量就是把继承来的变量作为自己的一个成员变量,就好象它们是在子类中直接声明一样,可以被子类中自己定义的任何实例方法操作。
-
所谓子类继承父类的方法就是把继承来的方法作为子类中的一个方法,就好象它们是在子类中直接定义了一样,可以被子类中自己定义的任何实例方法调用。
-
子类和父类在同一包中的继承性
- 如果子类和父类在同一个包中,那么,
- 子类自然地继承了其父类中不是private的成员变量作为自己的成员变量,
- 并且也自然地继承了父类中不是private的方法作为自己的方法,
- 继承的成员变量或方法的访问权限保持不变。
- 如果子类和父类在同一个包中,那么,
-
子类和父类不在同一包中的继承性
- 如果子类和父类不在同一个包中,那么,子类继承了父类的protected、public成员变量做为子类的成员变量,并且继承了父类的protected、public方法为子类的方法,继承的成员或方法的访问权限保持不变。
-
-
子类与对象
-
类继承了父类的很多东西,那么子类在创建对象的时候,他又是怎么生成自己的对象的呢。
-
子类生产的对象会有哪些东西呢。
-
子类对象的生成
-
子类创建对象时,
- 子类的构造方法总是先调用父类的某个构造方法,完成父类部分的创建;
- 然后再调用子类自己的构造方法,完成子类部分的创建。
- 如果子类的构造方法没有明显地指明使用父类的哪个构造方法,子类就调用父类的不带参数的构造方法 。
-
子类在创建一个子类对象时,不仅子类中声明的成员变量被分配了内存,而且父类的所有的成员变量也都分配了内存空间,但子类只能操作继承的那部分成员变量 。
-
子类可以通过继承的方法来操作子类未继承的变量和方法 .
-
结论:
- 创建子类对象时,子类总是按层次结构从上到下的顺序调用所有超类的构造函数。
- 如果继承和组合联用,要先构造基类的构造函数,然后调用组合对象的构造函数(组合按照声明的顺序调用)。
- 如果父类没有不带参数的构造方法,则在子类的构造方法中必须明确的告诉调用父类的某个带参数的构造方法,通过super关键字,这条语句还必须出现在构造方法的第一句。
-
-
-
成员变量的隐藏和方法重写
- 成员变量的隐藏
- 对于子类可以从父类继承的成员变量,只要子类中声明的成员变量和父类中的成员变量同名时,子类就隐藏了继承的成员变量。
- 在子类中要操作这个与父类同名的成员变量时,子类操作的是子类重新声明的这个成员变量。而不是被隐藏掉的。
- 成员变量的隐藏
-
方法重写
- 同样,子类通过重写可以隐藏已继承的实例方法。
- 重写的语法规则
- 如果子类继承了父类的实例方法,那么子类就有权利重写这个方法。
- 方法重写是指:
- 子类中定义一个方法,这个方法的类型和父类的方法的类型一致或是父类方法的类型的子类型,且这个方法的名字、参数个数、参数的类型和父类的方法完全相同.
- 重写的目的
- 子类通过方法的重写可以隐藏继承的方法,
- 子类通过方法的重写可以把父类的状态和行为改变为自身的状态和行为。
- 重写后方法的调用
- 子类创建的一个对象,如果子类重写了父类的方法,则运行时系统调用的是子类重写的方法;
- 子类创建的一个对象,如果子类未重写父类的方法,则运行时系统调用的是子类继承的方法;
- 重写的语法规则
- 同样,子类通过重写可以隐藏已继承的实例方法。
-
super
关键字- 用
super
操作被隐藏的成员变量和方法- 子类可以隐藏从父类继承的成员变量和方法,
- 如果在子类中想使用被子类隐藏的成员变量或方法就可以使用关键字
super
。 - 比如
super.x
、super.play()
就是访问和调用被子类隐藏的成员变量x
和方法play()
.
- 使用
super
调用父类的构造方法- 子类不继承父类的构造方法,
- 因此,子类如果想使用父类的构造方法,必须在子类的构造方法中使用,并且必须使用关键字
super
来表示,而且super()
必须是子类构造方法中的头一条语句。
- 用
-
final关键字
- final关键字可以修饰类、成员变量和方法中的局部变量。
- 可以使用final将类声明为final类。final类不能被继承,即不能有子类。
如: final class A { … … }
- 如果用final修饰父类中的一个方法,那么这个方法不允许子类重写。
- 如果成员变量或局部变量被修饰为final的,就是常量。
-
对象的上转型对象
-
假设,A类是B类的父类,当用子类创建一个对象,并把这个对象的引用放到父类的对象中时,称对象a是对象b的上转型对象
-
上转型对象的使用
- 上转型对象不能操作子类新增的成员变量;不能调用子类新增的方法。
- 上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法。
- 如果子类重写了父类的某个实例方法后,当用上转型对象调用这个实例方法时一定是调用了子类重写的实例方法。
-
-
继承与多态
- 多态性就是指父类的某个方法被其子类重写时,可以各自产生自己的功能行为。
-
abstract类与abstract方法
- 用关键字abstract修饰的类称为abstract类(抽象类)。
例如: abstract class A { … … }
- 用关键字abstract修饰的方法称为abstract方法(抽象方法)
例如: abstract int min(int x,int y);
- abstract类有如下特点
- 和普通的类相比,abstract类里可以有abstract方法。也可以没有。对于abstract方法,只允许声明,不允许实现,而且不允许使用final修饰abstract方法。
- 对于abstract类,不能使用new运算符创建该类的对象,只能产生其子类,由子类创建对象。
- 如果一个类是abstract类的子类,它必须具体实现父类的所有的abstract方法。
- 用关键字abstract修饰的类称为abstract类(抽象类)。
-
面向抽象编程
- 在设计一个程序时,可以先声明一个abstract类,通过在类中声明若干个abstract方法,表明这些方法在整个系统设计中的重要性,方法体的内容细节由它的非abstract子类去完成。
- 然后利用多态实现编程。
- 使用多态进行程序设计的核心技术是使用方法重写和上转型对象,即将abstract类声明对象作为其子类的上转型对象,那么这个上转型对象就可以调用子类重写的方法。
- 所谓面向抽象编程,是指当设计某种重要的类时,不让该类面向具体的类,而是面向抽象类,即所设计类中的重要数据是抽象类声明的对象,而不是具体类声明的对象。
-
开-闭原则
- 所谓“开-闭原则”(Open-Closed Principle)就是让设计的系统应当对扩展开放,对修改关闭。
- 在设计系统时,应当首先考虑到用户需求的变化,将应对用户变化的部分设计为对扩展开放,而设计的核心部分是经过精心考虑之后确定下来的基本结构,这部分应当是对修改关闭的,即不能因为用户的需求变化而再发生变化,因为这部分不是用来应对需求变化的。
- 如果系统的设计遵守了“开-闭原则”,那么这个系统一定是易维护的,因为在系统中增加新的模块时,不必去修改系统中的核心模块。
重点和难点
-
重点:类的继承性、上转型对象和多态技术
-
难点:理解上转型对象和多态技术的理解和运用
总结
- 继承是一种由已有的类创建新类的机制。
- 子类继承父类的成员变量。
- 子类继承父类的方法。
- 子类继承过程中可以实现变量隐藏与方法重写。
- 上转型对象可以访问子类继承或隐藏的成员变量,也可以调用子类继承的方法或子类重写的实例方法
- 多态是面向对象编程的又一重要特性。子类可以体现多态,即子类可以根据各自的需要重写的父类的某个方法,子类通过
- 法的重写可以把父类的状态和行为改变为自身的状态和行为。
- 熟练使用上转型对象以及面向抽象编程的思想,以便体现程序设计所提倡的“开-闭”原则。