阿里巴巴难度系数五颗星的试题,小白竟然说很简单

作者:神秘网友 发布时间:2020-09-20 11:54:37

阿里巴巴难度系数五颗星的试题,小白竟然说很简单

阿里巴巴难度系数五颗星的试题,小白竟然说很简单

牛客网上有道阿里巴巴的面试题,网站显示该题难度系数五颗星

阿里巴巴难度系数五颗星的试题,小白竟然说很简单

public class Base
{
    private String baseName = "base";
    public Base(){
        callName();
    }

    public void callName(){
        System. out. println(baseName);
    }

    static class Sub extends Base{
        private String baseName = "sub";
        public void callName(){
            System. out. println (baseName) ;
        }
    }
    public static void main(String[] args){
        Base b = new Sub();
    }
}

咋一看,好像是考察类的加载顺序,应该会先加载Sub类,所以会输出sub
也有人表示不服,虽然会先从Sub类开始加载,但根据加载顺序,会先加载父类的构造函数
所以结果会输出base
——————————————————————————————————
但答案是null~
阿里巴巴难度系数五颗星的试题,小白竟然说很简单

阿里巴巴难度系数五颗星的试题,小白竟然说很简单

我们知道一般的类加载顺序是:先静态变量,然后静态代码块,其次是成员变量和普通代码块,最后是构造函数

new Sub()先加载基类成员变量,baseName = "base",没问题

然后加载基类构造函数public Base(),,但是构造函数中调用了callName

关键就在这个callName,它在子类Sub中也存在

再仔细看一下main方法Base b = new Sub();

恰好满足多态的三个必要条件

1、 继承

2、 子类重写父类方法

3、 父类引用指向子类对象

所以在父类的构造函数中调用的callName实际会调用子类的callName,而此时子类中的成员变量baseName还未加载,没有被赋值,所以为null

此处 不仅仅考察了类的加载顺序,还考察了java多态的特性

ON java 8这本书中第九章给出了相关解释
阿里巴巴难度系数五颗星的试题,小白竟然说很简单

阿里巴巴难度系数五颗星的试题,小白竟然说很简单
后期绑定——多态
阿里巴巴难度系数五颗星的试题,小白竟然说很简单

也就是说,父类的引用指向子类的对象时,调用共有方法,会执行子类方法,改造一下验证

public class Base {
    private String baseName = "base";
    public Base() {
        callName();
    }

    public void baseMethod(){
        System. out. println("baseMethod");
    }

    public void commonMethod(){
        System. out. println("commonMethod for Base");
    }

    public void callName() {
        System. out. println("Base callName(): "+baseName);
    }

    static class Sub extends Base {
        private String baseName = "sub";

        public void subMethod(){
            System. out. println("subMethod");
        }

        public void commonMethod(){
            System. out. println("commonMethod for Sub");
        }

        public void callName() {

            System. out. println ("Sub callName(): "+baseName) ;
        }
    }
    public static void main(String[] args) {

        System. out. println("************父类引用指向子类的对象**************");
        Base baseWithSub = new Sub();
        baseWithSub.baseMethod();
        baseWithSub.commonMethod();

        System. out. println("***********父类引用指向自己的对象***************");

        Base base = new Base();// 
        base.baseMethod();
        base.commonMethod();

        System. out. println("##############子类引用指向子类的对象##################");
        
        Sub sub = new Sub();
        sub.subMethod();
        sub.commonMethod();

    }
}

结果
阿里巴巴难度系数五颗星的试题,小白竟然说很简单

总结一下就是
1、父类的引用指向子类的对象,通过父类的引用调用父类、子类中均有的方法,那么java会自动调用子类的方法
2、父类的引用指向父类的对象,调用的是自己的方法

3、子类引用指向子类的对象,在涉及父类方法调用时,比如调用父类构造函数、父类代码块涉及重写函数等参照第一条,调用子类的方法

阿里巴巴难度系数五颗星的试题,小白竟然说很简单相关教程

  1. LeetCode刷题之数据库-185. 部门工资前三高的所有员工(难度-困
  2. 38. 外观数列
  3. 转统计学之三大相关性系数(pearsonspearmankendall)
  4. 零售快消的AI应用难度再降低百度EasyDL推出辅助标注功能
  5. 一天一大 lee(冗余连接 II)难度:困难-Day20200917
  6. 阿里巴巴集团董事会主席兼CEO张勇再谈新技术不仅是免疫力更是生
  7. 一天一大 lee(全排列 II)难度:中等-Day20200918
  8. 地狱难度字节跳动Android高级岗说说RecyclerView的回收复用机制