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

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是正確答案。