多态的三个陷阱

作者: Shingoooooo | 来源:发表于2016-10-27 15:25 被阅读49次

    一、只有非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()方法时,由于是静态方法而不能表现多态,因此访问的是基类的方法。这种现象由静态方法是属于类的,与对象无关也可以很好的解释。

    相关文章

      网友评论

        本文标题:多态的三个陷阱

        本文链接:https://www.haomeiwen.com/subject/lifsuttx.html