多态的三个陷阱

一、只有非private方法才可以被覆盖。

public class PrivateOverride { 
    private void f() { 
        System.out.println("private f()"); 
    }
    public static void main(String[] args) { 
        PrivateOverride po = new Derived();//UpCasting
        po.f(); 
    }
}

class Derived extends PrivateOverride { 
    public void f() { 
        System.out.println("public f()"); 
    }
} /* Output:
private f()
*/

在上面的程序中,导出类的f()是一个全新的方法,因为基类中的f()方法是private型的,在导出类中是不可见的,就更不能覆盖它了。


二、只有普通的方法调用可以是多态的。

即:如果直接访问某个域,这个访问就会在编译器进行解析。

class Super {
  public int field = 0;
  public int getField() { return field; }
}

class Sub extends Super {
  public int field = 1;
  public int getField() { return field; }
  public int getSuperField() { return super.field; }
}

public class FieldAccess {
  public static void main(String[] args) {
    Super sup = new Sub(); // Upcast
    System.out.println("sup.field = " + sup.field +
      ", sup.getField() = " + sup.getField());
    Sub sub = new Sub();
    System.out.println("sub.field = " +
      sub.field + ", sub.getField() = " +
      sub.getField() +
      ", sub.getSuperField() = " +
      sub.getSuperField());
  }
} /* Output:
sup.field = 0, sup.getField() = 1
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0
*/

在上面的程序中,Super sup = new Sub();这句话对Sub对象转型为Super引用,sup.field访问的是Super类的field变量,而sup.getField()则访问的是Sup类的getField()方法。即:访问域没有表现多态,而访问普通的方法时表现了多态。


三、如果某个方法时静态的,它的行为就不具有多态性。

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()
*/

在上面的程序中,StaticSuper sup = new StaticSub();这行代码将StaticSub对象转型为StaticSuper引用,当调用sup,staticGet()方法时,由于是静态方法而不能表现多态,因此访问的是基类的方法。这种现象由静态方法是属于类的,与对象无关也可以很好的解释。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容