JavaSE 巩固 多态的细节研究

多态是 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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值