题一,如下代码的执行结果:
class Person{ String name = "No name"; public Person(String nm){name = nm;} } class Employee extends Person{ String empID = "0000"; public Employee(String id){empID = id;} } class EmployeeTest{ public static void main(String[] args){ Employee e = new Employee("4321"); System.out.println(e.empID); } }
题二,如下代码的执行结果:
class Atom{ Atom(){System.out.print("atom ");} } class Rock extends Atom{ Rock(String type){System.out.print(type);} } public class Mountain extends Rock{ Mountain(){ super("granite "); new Rock("granite "); } public static void main(String[] a){new Mountain();} }
题三,对如下代码执行哪些调整,可以使Sub类正常执行:
1. class Super{ 2. private int a; 3. protected Super(int a){this.a = a;} 4. } ... 11. class Sub extends Super{ 12. public Sub(int a){super(a);} 13. public Sub(){this.a = 5;} 14. }
调整选项:
A. Change line 2 to: public int a; B. Change line 2 to: protected int a; C. Change line 13 to: public Sub(){this(5);} D. Change line 13 to: public Sub(){super(5);} E. Change line 13 to: public Sub(){super(a);}
这两道题考察的重点是类的继承,考点是父类构造器的调用。
关于父类构造器的调用需要注意以下几点:
- 子类不会获得父类的构造器;
- 在一个构造器中调用另一个重载的构造器可以使用this调用,在子类构造器中调用父类构造器可以使用super调用;
- 使用super调用父类构造器必须出现在子类构造器执行体的第一行;
- 不管是否使用super调用父类构造器,子类构造器总会调用父类构造器,调用形式有如下三种:
- 子类构造器使用super显式调用父类构造器;
- 子类构造器使用this调用重载的构造器,重载的构造器调用父类构造器;
- 若子类构造器执行体中没有super调用,也没有this调用,系统将会在执行子类构造器前隐式调用父类的无参数构造器。
- 当调用子类构造器初始化子类对象时,父类构造器总会在子类构造器前执行。以此向上类推,创建任何java对象,最先执行的总是Object类的构造器;
- 如果没有为一个类提供自定义构造器,系统会默认为这个类提供一个无参数构造器;反之,若已经为这个类提供了自定义构造器,系统将不会为这个类提供隐式无参构造器。
题目分析:题一中Person类没有无参数构造器,子类Employee的构造器中也没有使用super调用Person类中已定义的构造器,那么子类将无法找到无参数的Person类构造器,无法编译。
附上题一编译结果:
根据以上的第五条可以推断出题二的执行结果。
题二执行结果:
对于题三,先分析所给的代码,着重关注Sub类的第二个构造器,这个构造器需要隐式调用父类的无参构造器。父类没有提供无参构造器。因此需要为父类Super添加一个无参构造器,或调整Sub类的第二个构造器,使之调用Super类的有参数的构造器。答案中CD正确,E中调用的父类成员变量a的作用域错误。