继承的缺陷(可能有坑的地方)

1、“覆盖”私有方法

class Super{
    public void fun(){
        System.out.println("Super");
    }
    public static void main(String[] args){
        Super sup = new Sub();
        sup.fun();
    }
}
class Sub extends Super{
    public void fun(){
        System.out.println("Sub");
    }
}

  这里的Super类有一个fun方法,Sub继承自Super重载了fun方法。

  可以看看输出是:

Sub

  Super中的sun方法被重载了。

  将Super中的fun方法修改为private,

class Super{
    private void fun(){
        System.out.println("Super");
    }
    public static void main(String[] args){
        Super sup = new Sub();
        sup.fun();
    }
}
class Sub extends Super{
    public void fun(){
        System.out.println("Sub");
    }
}

  输出就是:

Super

  可以看到fun方法并没有被重写,这种情况很容易理解,因为private类型的方法对子类是不可见的,Sub中的fun()是全新的方法,所以重载失败。

2、域的访问操作

class Super{
    public int id = 0;
    public int getId(){
        return id;
    }
}
class Sub extends Super{
    public int id = 1;
    public int getId(){
        return id;
    }
    public int getSuperId(){
        return super.id;
    }
}
public class test {
    public static void main(String[] args){
        Super sup = new Sub();
        System.out.println("sup.id = " + sup.id + "sup.getid() = " + sup.getId());
        Sub sub = new Sub();
        System.out.println("sub.id = " + sub.id + "sub.getid() = " + sub.getId() + "sub.getSuperId() = " + sub.getSuperId());
    }
}

  输出是:

sup.id = 0sup.getid() = 1
sub.id = 1sub.getid() = 1sub.getSuperId() = 0

  这里可以看到Sub对象转型为Super对象的时候,任何的域操作都不是多态的,证据是sup.id的结果是0,然后getid()的结果却是1,从这里可知Super.id和Sub.id是分配到了不同的内存空间中,Super的id需要使用super.id才能在Sub中调用,第二行输出可证。

3、构造器中多态的行为

  如果在构造器中调用了将会被重写的方法会发生什么?

class Super{
    Super(){
        getId();
    }
    public void getId(){
        System.out.println("super");
    }
}
class Sub extends Super{
    public void getId(){
        System.out.println("sub");
    }

}
public class test {
    public static void main(String[] args){
        Super sup = new Sub();
    }
}

  输出自然是被重载之后的:

sub

  那如果在构造器中调用正在构造的对象的某个动态绑定方法呢?

class Super{
    Super(){
        getId();
    }
    public void getId(){
        System.out.println("super");
    }
}
class Sub extends Super{
    private int id = 0;
    Sub(int i){
        id = i;
        getId();
    }
    public void getId(){
        System.out.println("sub.id = " + id);
    }

}
public class test {
    public static void main(String[] args){
        Super sup = new Sub(5);
    }
}

  这里的Sub构造器将接受一个int参数,然后赋值给id,然后调用getId输出id的值,因为Super是Sub的父类所以Super的构造器也会被调用,可以先看看输出:

sub.id = 0
sub.id = 5

  Super中输出sub.id = 0,而不是super的原因是被getId方法被重载了,id的值为0的原因是因为,Super的构造器是先于Sub的构造器运行的,id变量的赋值是Sub的构造器进行的,所以Super构造器运行的时候id的值为默认值0

原文地址:https://www.cnblogs.com/xxbbtt/p/8275994.html