Java 字段不参与多态性

  1. 两个例子
    1. 例子一:
    2. 例子二:
  2. 字段不参与多态性

两个例子

例子一:

  • 父类:

    public class Father {
        int age;
            
        public Father() {
            age = 50;
        }
    }
    
  • 子类:

    public class Son extends Father {
        public Son() {
            age = 25;
        }
    }
    
  • 多态的创建子类,看看年龄到底是多少:

    public class FieldHasNoPolymorphic {
        public static void main(String[] args) {
            Father guy = new Son();
            System.out.println("This guy's age is " + guy.age);
        }
    }
    

例子一的输出:This guy's age is 25

很合理对吧?毕竟以前学Java SE的时候,不管是视频还是书里,都是说编译看左边,运行看右边,即父类变量的引用( guy )指向了子类对象( Son ),那么代码访问子类的年龄,自然是输出 25

例子二:

  • 父类:同例子一

  • 子类:

    public class Son extends Father {
        // 跟例子一相比多声明了一个父类同名字段
        int age;
        ...
    }
    
  • 同样是多态的创建子类,看看年龄是多少:

    public class FieldHasNoPolymorphic {
        public static void main(String[] args) {
            Father guy = new Son();
            System.out.println("This guy's age is " + guy.age);
        }
    }
    

例子二的输出:This guy's age is 50

奇怪,明明在子类构造方法中给子类 age 初始化为了 25 ,怎么输出是 50

字段不参与多态性

字段永远不会参与多态,当子类声明父类的同名字段时,虽然在子类的内存中两个字段都会存在,但是子类的字段会遮蔽父类的同名字段

什么意思呢?假设将在父类继承而来的 age 字段叫做 ageF ,而子类中声明的 age 字段叫做 ageS ,虽然内存中这两个字段都会存在,但是子类的字段遮蔽了父类的同名字段,所以子类的构造方法中实际上是对 ageS 进行了初始化,但是通过多态创建的子类对象时,guy.age 访问的却是 ageF ,这就是为什么例子二的年龄输出是 50 而不是 25


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。