super关键字
子类override(覆盖)父类的函数
override时,使用super
调用父类的方法。
1 | //超类,员工 |
super在构造器中的应用
1 | public Manager(String n, double s, int year, int mouth, int day){ |
多态
一个对象变量可以指示多种实际类型的现象————多态(polymorphism) 在运行时自动选择调用那个方法的现象————动态绑定(dynamic binding)
例如:
Employee e = new Employee();
e = new Manage(); // is ok
此时,对象变量e
也可以引用Manager
的对象。
Manage boss = new Manage(...);
Employee[] staff = new Employee();
调用对象方法的执行过程
- 编译器查看对象的声明类型和方法名。假设调用
x.f(param)
,且隐式参数x声明为C类的对象。编译器一一列举所有C类中名为f的方法和其超类中访问属性为public且名为f的方法。 - 编译器查看调用方法时提供的参数类型。这个过程叫做重载解析(overloading resolution)
- 如果是private方法、static方法、final方法或者构造器,那么编译器会准确地知道应该调用哪个方法(编译器可以在编译阶段就完成绑定),这种调用方式叫静态绑定(static binding)。与此对应的是,调用的方法依赖于隐式参数的实际类型(编译器在编译阶段不知道要调用哪个方法,直到运行时才能确定),并在运行时实现动态绑定。有一个很好的例子解释这两个概念——lingzhm-动态绑定
- 程序运行时,若是动态绑定调用方法,那就先从本类中寻找,否则从超类中寻找。(每个类都有一个方法表method table)
阻止继承:final类和方法
不允许扩展(被继承)的类被称为final类。
例如下例子中的Executive类就不能有子类。
1 | final class Executive extends Manager{ |
类中的方法也可以final,那么子类就不能覆盖这个方法。
1 | class Employee{ |
抽象类,abstract
用于表示某种很抽象的、上层的、更通用的类。例如图中的Person
类。
- 一般来说,包含一个或多个抽象方法的类本身必须被声明为抽象的。
- 抽象类不能被实例化!
1 | abstract class class Person{ |
可以定义抽象类的对象变量,但只能引用非抽象子类的对象:
Person p = new Student("Vince Vu","Economics");
照着书上写了abstract的demo
输出为:
Harry Hacker,an employee with a salary of 50000.00
Maria Morris,a student majoring in computer science
受保护访问,Protected
若超类的某个域被声明为protected,那么子类就可以直接访问这个protected域。
- private-仅本类可见
- public-所有类可见
- protected-对本包和所有子类可见
- 默认-对本包可见