zoukankan      html  css  js  c++  java
  • 继承的缺陷(可能有坑的地方)

    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

  • 相关阅读:
    消息队列RocketMQ版最佳实践订阅关系一致
    Java8 stream、List forEach 遍历对象 List 对某一字段重新赋值
    SQL的嵌套查询与连接查询
    Xshell7 个人可以申请免费使用正版
    @NotEmpty、@NotBlank、@NotNull 区别和使用
    List集合日常总结
    Time Zone(时区)
    Arrays.asList() 和Collections.singletonList()的区别
    GitBash生成SSH密钥
    Mysql中用SQL增加、删除、修改(包括字段长度/注释/字段名)总结
  • 原文地址:https://www.cnblogs.com/xxbbtt/p/8275994.html
Copyright © 2011-2022 走看看