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


    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

  • 相关阅读:
    centos7不能上网问题
    数据库修改为utf8mb4
    查看Linux系统信息
    如何查看Linux是否安装了gcc和gcc-c++
    nginx启动报错
    centos7无法上网问题
    notepad++如何将换行替换成其它符号?
    JAVA DESUtils加密工具
    Django之Model(一)--基础篇
    深刻理解Python中的元类(metaclass)以及元类实现单例模式
  • 原文地址:https://www.cnblogs.com/xxbbtt/p/8275994.html
Copyright © 2020-2023  润新知