构造器中的多态行为

   java中,多态只会发生于非final/private的方法中,static 方法、属性、构造器、private/final方法都不具备多态行为。但是,当构造器中出现多态时,常常引起不必要的且难以发现的麻烦。看如下实例:

public class Animal {

    Animal() {
        System.out.println("Animal start to run");
        run();
        System.out.println("Animal end  run ");
    }

    void run() {
        System.out.println("Animal.run");
    }

}

class Cat extends Animal {

    private String name = "喵喵";

    Cat(String name) {
        this.name = name;
        System.out.println("Cat.Cat,init name" + this.name);
    }

    @Override
    void run() {

        System.out.println(name + " Cat.run");
    }

    public static void main(String[] args) {
        new Cat("豆豆");
    }

}

运行如上程序,我们会发现,以下结果:

Animal start to run
null Cat.run
Animal end  run 
Cat.Cat,init name豆豆

我们发现,在初始化Cat时,我们预想,初始化父类对象时,将会调用Cat重写的run方法,并打印出 “喵喵 Cat.run”,但是结果却是出乎预料,而是“null Cat.run”。

那么是什么导致这个结果呢?这个其实原因与java对象初始化顺序有关。

第一:初始化子类对象时,总是先向上初始化父类对象。级别越高,越先初始化,Object最先被初始化。本例中,在初始化Cat对象时,那么先调用父类对象Animal的构造器,来初始化父类对象。那么当程序运行至run方法时,将调用子类Cat重写后的run方法。

第二:类中的成员变量,依据声明顺序初始化。本例中,Cat 构造器默认第一句调用Animal构造器,此时,Cat尚未被初始化,Cat中的成员变量name 只是分配了内存地址并被系统赋予默认值,此时为null。

        鉴于以上原因,在Animal初始化时调用run方法时,name仍然没有被初始化,故而,输出了与预想不同的结果。

总结:在父类中调用会产生多态效果的方法时,应当谨慎,甚至避免调用此类方法。在父类构造器中,应当调用private ,final ,static 修饰的不具备多态特性的方法,这样会避免以上情况的发生。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值