@Data
    static class Parent{
        String name;

        @Override
        public String toString() {
            return "Parent{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    @Data
    static class Son extends Parent{
        private String nickName;

        @Override
        public String toString() {
            return "Son{" +
                    "name='" + name + '\'' +
                    ", nickName='" + nickName + '\'' +
                    '}';
        }
    }

public static void main(String[] args) {
        Parent p1 = new Parent();
        Parent p2 = new Son();
        p1.setName("parent1");
        p2.setName("parent2");

        Son s1 = new Son();
        s1.setNickName("s1");
        s1.setName("s1-p1");

        System.out.println((Parent)s1); // LSP-ok : Son{name='s1-p1', nickName='s1'}
        System.out.println((Son)p1); // ClassCastException
        System.out.println((Son)p2); // OK-no error or exception
    }

结论:

  1. 根据 LSP : 里氏代换原则(Liskov Substitution Principle)

父类出现的地方, 子类型都可以替换之; 所以子类随时可以强转为父类
而且输出的是

Son{name='s1-p1', nickName='s1'}
说明强转后, 还是子类的实例, 子类有的父类没有的字段也会保留;
  1. 但是 父类强转子类有2中情形:

可转: 父类初始化new的是子类的实例对象: 其实就是说真实的堆中的对象的类型是否匹配;
不可转: 父类初始化new的自身的实例对象:;


丰木
322 声望19 粉丝

遇见超乎想象的自己!