携程网的面试题,看答案都迷迷糊糊的 
- package com.gxlee;
 
  
- 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();
 
 -         System.out.println(b);
 
 -     }
 
 - }
 
  
- 求这段程序的输出。
 
  
- 解答此题关键在于理解和掌握类的加载过程以及子类继承父类后,重写方法的调用问题:
 
  
- 从程序的执行顺序去解答:
 
  
- 1、Base b = new Sub();
 
  
-   声明父类变量b对子类的引用,JAVA类加载器将Base,Sub类加载到JVM;
 
  
- 2、JVM为Base,Sub 的的成员开辟内存空间
 
  
-   此时,Base 和Sub类中的值为null;
 
  
- 3、new sub()
 
  
-   调用构造函数,由于Sub类继承自Base而无自定义构造器,因此先调用父类Base的无参构造;
 
  
- 4、父类午餐构造的本质为:
 
  
-   public Base(){
 
  
-   baseName= "base";
 
  
-   callName();
 
  
-     }
 
  
-   即将父类的baseName赋值为“base”,赋值后调用callName();
 
  
- 5、callName 在子类中被重写,因此调用子类的callName();
 
  
- 6、调用子类的callName,打印baseName
 
  
-   此baseName为子类Sub的成员变量,而此时该成员尚未初始化,因此为Null;
 
  
- 7、实际上在new Sub()时,实际执行过程为:
 
  
-   public Sub(){
 
  
-       super();
 
  
-    baseName = "sub"; 
 
  
-     }
 
  
-   可见,在baseName = "sub"执行前,子类的callName()已经执行,所以子类的baseName为默认值状态null;
 
 
  复制代码 
 
 |   
        
 
    
    
    
     
 
 |