Given:
public class SuperTest {
public static void main(String[] args) {
// statement1
// statement2
// statement3
}
}
class Shape {
public Shape() {
System.out.println("Shape: constructor");
}
public void foo() {
System.out.println("Shape: foo");
}
}
class Square extends Shape {
public Square() {
super();
}
public Square(String label) {
System.out.println("Square: constructor");
}
public void foo() {
super.foo();
}
public void foo(String label) {
System.out.println("Square: foo");
}
}
What should statement1, statement2, and statement3, be respectively, in order to produce the result?
Shape: constructor
Square: foo
Shape: foo
Square: foo
Shape: foo
A.
Square square = new Square("bar");
square.foo("bar");
square.foo();
B.
Square square = new Square("bar");
square.foo("bar");
square.foo("bar");
C.
Square square = new Square();
square.foo();
square.foo(bar);
D.
Square square = new Square();
square.foo();
square.foo("bar");
E.
Square square = new Square();
square.foo();
square.foo();
F.
Square square = new Square();
square.foo("bar");
square.foo();
題解
輸出的第1行為「Shape: constructor」,因此需要實體化出Shape物件才會執行第13行的程式。Square類別繼承Shape類別,不傳入參數實體化出Square物件也會執行到Shape的建構子。所以目前看來,statement1可以實體化出Square物件或是Shape物件,且選項A、B是錯誤的。
輸出的第2行為「Square: foo」,也就是要執行程式第35行,Square類別內的foo(String label)物件方法。所以statement1應該要實體化出Square物件,並且在statement2呼叫Square物件的foo方法時,必須傳入字串參數。因此選項C、D、E是錯誤的。
輸出的第3行為「Square: foo」,也就是要執行程式第17行,Shape類別內的foo()方法。這個方法在程式第31行,也就是Square類別內被覆寫,但覆寫的程式實作使用了「super」去呼叫了Shape類別原先的foo()方法,所以呼叫Square物件的foo()方法也會輸出「Square: foo」。選項F是正確答案。