java多态可扩展性缺陷

java多态可扩展性缺陷

1.覆盖了私有方法

private方法默认是final,即不可继承的,对导出类是屏蔽的,如果子类覆写了父类的同类方法,那么其实子类的方法是新的方法

Outer类:

private void f(){
        System.out.println("xxxx");
    }

public  static void main(String[] arg) {
        int[] a = new int[] { 1, 2, 3 };
        Outer o = new Oter1();
        o.f();
    }

Oter1类:

public void f(){
      System.out.println("xxx");
  }

输出: xxxx 这表明了o.f()其实是调用父类的f()方法,因为private方法关闭了内置在Java语言中动态绑定。所以子类只能覆盖非公共方法,那么我们在导出类中,对父类中的private方法,需要采用不同的方法名。

域和静态方法

例子:

    父类
class Super{
     public int field = 0;
     public int getField(){
         return field;
     }
 }
    子类
public class Sub extends Super {
          
   
    int field = 1;

    public int getField(){
        return field;
    }

    /**
     * sub拥有的field有从super中继承的域,也有自己的域,为了得到父类的field域,需要通过super关键字返回父类的field字段
     * @return 父类的field域
     */
    public int getSuperField(){
        return super.field;
    }

    public  static void main(String[] arg) {
        Super sup = new Sub();
        //Sub对象自动转化成Super对象的引用时,域访问操作是由编译器决定的,所以这里不是多态的,sup.field得到的是不是Sub对象的域,而是Super对象中的域
        //但是getField是多态的操作,得到的field域是Sub域中的值
        System.out.println("sup.field= " + sup.field +", sup.getField()= "+sup.getField());

        Sub sub = new Sub();
        //sub.getField得到的是自己声明的这个field域,sub.getSuperFiled得到的是父类的filed域
        System.out.println("sub.filed= " + sub.field +", sub.getFiled()= " + sub.getField()+",sub.getSuperFiled()= " +sub.getSuperField());;
    }

}

输出结果: sup.field= 0, sup.getField()= 1 sub.filed= 1, sub.getFiled()= 1,sub.getSuperFiled()= 0


这个结果表明,编译器为Super父类和Sub子类分别分配的不同的内存空间(放在堆栈Stack中,Stack位于RAM中,通过堆栈指针的移动得到CPU中的变量值)。也就是说,子类有2个field,一个是自己的,另一个是父类的。要是使用父类的field,就要用super关键字。

静态方法

例子:

    子类
public class StaticSub extends StaticSuper {
          
   

    /**
     * static方法体不会产生多态度,所以第一个打印的值为父类的方法返回的值,也即getStaticString()--fromSuper
     * @return
     */
    public static String getStaticString() {
        return "getStaticString()----fromSub";
    }

    public  static void main(String[] arg) {
        StaticSuper staticSuper = new StaticSub();

        System.out.println(staticSuper.getStaticString());
    }

}
    父类
public class StaticSuper {
    public static String getStaticString() {
        return "getStaticString()--fromSuper";
    }
}

输出: getStaticString()–fromSuper


由输出可以看出,static方法是由与类(这里是指StaicSuper)绑定的,而不是与对象(这里是指new StaticSub())绑定的。

经验分享 程序员 微信小程序 职场和发展