5. RE - 向上类型转换
Upcasting
• 向上类型转换是指引用可以指向该类及其子类的所有对象, 比如, 按照如下继承关系:
Class A A a = new A();
a = new B();
a = new C(); // A的引用可以指向A/B/C
B b = new C();
Class B
C c = new C();
Class C
• 方法在声明时可以指定某个基类或者接口(比如A), 而在调用时则可以
传入相应的具体实现(比如B/C), eg:
// 方法声明
void f(A a) {......}
// 调用
A a = new B();
f(a);
f(new C())
7. 多态
• 由于Upcasting特性, 方法(比如:void f(A))在调用时输入的实参(比如: p1)
有可能是不同的具体实现类型: 形参类型本身(class A)及其子类型(class
B); 考虑这样一个问题: 如果在方法(f)内调用该实参(p1)的某个方法(比
如: pf), 那么最终调用的是class A还是class B上面的实现? 示例:
class A {
void pf()...
}
class B extends A {
void pf() ... // override
}
class C {
f(A p1) ... // 形参类型是A
}
// 使用
C c = new C();
A a = new B();
c.f(a); // 这里会调用class A里面的pf实现还是class B的?
9. Pitfall: private方法
• 在《 7, Reusing Classes 》章节中讲到private方法默认是final, 因
此不能被覆盖;
• 示例:
public class PrivateOverride {
private void f() { print("private f()"); }
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f(); // output: private f();
}
}
class Derived extends PrivateOverride {
public void f() { print("public fs()"); }
}
• 示例: demo/PrivateOverride.java
10. Pitfall: 属性和静态方法
• 对于类属性以及静态方法, 不会有多态行为;
• 示例:
class A {
public int i = 1;
public static void f()...
}
class B extends A {
public int i = 2;
public static void f()...
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
a.f(); //
}
}
• 示例: demo/Demo2.java
• 示例: demo/Demo3.java
11. 扩展
• 子类可以覆盖父类的方法, 同时也可以通过添加其他的方法进行扩展;
比如:
class A {
void f()...
void g() ...
}
class B extends A {
void m()... // m, n方法是一种扩展
void n()...
}
• 结合向上转型和多态, 可以通过父类的接口调用子类的方法, 比如:
A a= new B();
a.f();
a.g(); // 运行时与B中的方法进行绑定
但是不能调用子类扩展的其他方法,
a.m();
a.n(); // 编译错误