天天看点

第8章 多态(java编程思想)

8.2.4 缺陷 :覆盖私有方法

//: polymorphism/PrivateOverride.java
// Trying to override a private method.

import static net.mindview.util.Print.*;

public class PrivateOverride {
  private void f() { print("private f()"); }
  public static void main(String[] args) {
    PrivateOverride po = new Derived();
    po.f();
  }
}

class Derived extends PrivateOverride {
  public void f() { print("public f()"); }
} /* Output:
private f()
*///:~

           

我们所期望的输出是public f(),但是由于private方法自动认为是final类的,对于导出类是屏蔽的,在这种情况下,f()就是一个全新的方法,因此基类中的f()不可被重载。

结论就是,只有非private方法猜可以被覆盖,在导出类中基于基类的方法,最好采用不同的名字。

8.2.4 缺陷,域和静态方法

如果某个方法是静态的,他的行为不具备多态性。

//: polymorphism/StaticPolymorphism.java
// Static methods are not polymorphic.

class StaticSuper {
   public static String staticGet() {
    return "Base staticGet()";
  }
  public  String dynamicGet() {
    return "Base dynamicGet()";
  }
}

class StaticSub extends StaticSuper {
  public static String staticGet() {
    return "Derived staticGet()";
  }
  public String dynamicGet() {
    return "Derived dynamicGet()";
  }
}

public class StaticPolymorphism {
  public static void main(String[] args) {
    StaticSuper sup = new StaticSub(); // Upcast
    System.out.println(sup.staticGet());
    System.out.println(sup.dynamicGet());
  }
} /* Output:
Base staticGet()
Derived dynamicGet()
*///:~

           

8.3 构造器和多态

基类的构造器总是在导出类的构造过程中被调用,而且按照继承层次逐渐向上链接,以使每个构造器都能被调用。导出类只能访问自己的成员,不能访问基类中的成员(基类成员通常为private)。

8.5 用继承进行设计

学习多态之后,看起来似乎所有东西都可以被继承,因为多态是一种如此巧妙的工具。事实上,当我们使用现成的类来建立新类时,如果首先考虑使用继承技术,反而会加重我们的设计负担,是事情变得复杂起来,更好的选择是使用“组合”,组合不会强制我们的程序设计进入继承的层次结构,而且,组合更加灵活,因为它可以动态的选择类型。

8.5.1 纯继承与扩展

继承可以保证所有的导出类具有基类的接口,但如果导出类扩展了接口,一旦我们向上转型,就不能调用那些新方法。这时我们需要向下转型,以便能够访问该类型所扩充的方法。

8.5.2 向下转型与运行时的类型识别

在java中,为了保证安全,所有的向下转型都会被检查。这种检查的行为被称为RTTI。