JavaSE 巩固 多态的细节研究

来源:互联网 发布:工作中可优化的流程 编辑:程序博客网 时间:2024/06/09 19:26

多态是 Java 成为高级语言的特性之一,它可以实现运行时动态绑定,正是因为如此,在使用多态的时候有许多细节的地方需要注意。

1. 多态和字段无关

代码

public class FieldAccess {    public static void main(String[] args) {        Super sup = new Sub();        System.out.println("sup.field = " + sup.field + "sup.getField() = " + sup.getField());        Sub sub = new Sub();        System.out.println("sub.field = " + sub.field + "sub.getField() = " + sub.getField() + "sub.getSuperField() = " + sub.getSuperField());    }}class Super {    public int field = 0;    public int getField () {        return field;    }}class Sub extends Super {    public int field = 1;    public int getField () {        return field;    }    public int getSuperField () {        return super.field;    }}

运行结果

sup.field = 0, sup.getField() = 1
sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0

2. 多态和静态方法无关

代码

public class StaticPolymorphism {    public static void main(String[] args) {        StaticSuper sup = new StaticSub();        System.out.println(sup.staticGet());// 调用父类的静态方法,这时候只和类有关        System.out.println(sup.dynamicGet());// 调用子类的方法    }}class StaticSuper {    public static String staticGet() {        return "Base staticGet()";    }    public String dynamicGet() {        return "Base dynamicGet()";    }}class StaticSub extends StaticSuper {    public static String staticGet() {        return "Derived staticGet()";    }    public String dynamicGet() {        return "Derived dynamicGet()";    }}

运行结果

Base staticGet()
Derived dynamicGet()

3. 多态时的私有方法

代码

public class PrivateOverride {    private void f () {        System.out.println("private f()");    }    public static void main(String[] args) {        PrivateOverride derived = new Derived();        derived.f();// private f()    }}class Derived extends PrivateOverride {    public void f() {        System.out.println("public f()");    }}

运行结果

private f()

4. 警惕不正当的初始化

问题代码

class Father {    public void show() {        System.out.println("Father.show()");    }    public Father() {        System.out.println("Father before show()");        show();//这里将会调用子类的方法, 此时son中的money没有初始化, 有安全风险        System.out.println("Father after show()");    }}class Son extends Father {    private int money = 100;    public Son(int money) {        this.money = money;        System.out.println("Son constructor, money = " + money);    }    @Override    public void show() {        System.out.println("Son.show(), money = " + money);    }}public class PolyConstructors {    public static void main(String[] args) {        new Son(88);    }}

运行结果

Father before show()
Son.show(), money = 0
Father after show()
Son constructor, money = 88

在多态的情况下,这种问题一定要格外小心,最好的方法是在构造的时候不要使用多态。

原创粉丝点击