2009-12-15 3 views
1

을 상속 :자바는 방법 질문

class A{ 
    private static String staticProperty = " a "; 
    String getStaticProperty() { return staticProperty; } 
} 

class B extends A { 
    private static String staticProperty = " b "; 
    public static void main(String[] args){ 
     new B().go(new A()); 

    } 
    void go(A t){ 
     String s = t.getStaticProperty() + B.staticProperty + staticProperty + (new B().getStaticProperty()); 
     System.out.println(s); 
    } 
} 

출력 무엇입니까? 내가 완벽하게 a b b을 이해하지만, "A"의 말을 이해하지 못하는 a b b a

출력은 여기에있다. 메서드를 상속하면 (이 경우 B는 A에서 getStaticProperty()를 상속하고 해당 메서드는 부모에서 정적 변수 (staticProperty)를 반환합니다.이 정적 변수는 자식에서 다시 정의하므로 부모 정적 변수를 항상 사용합니다 값??

그런데 정적 식별자를 제거하고 staticField를 클래스의 인스턴스 멤버로 만들면 같은 결과가 반환됩니다. 개인에서 공용으로 액세스 수정자를 수정하면 동일한 결과가 리턴됩니다. 내가보고 싶었던 것을 얻기 위해 getStaticProperty 메소드를 오버라이드해야했습니다.

답변

4

필드 액세스는 메소드 액세스와 마찬가지로 dynamic dispatch과 같지 않습니다. 즉, 필드를 재정의 할 수 없습니다. 클래스 A에서이 줄 :

String getStaticProperty() { return staticProperty; } 

따라서 같은 이름을 가진 클래스 A. 클래스 B의 필드에 필드 staticProperty을 의미하는 것은 무관하다, 또는 오히려 : 그것은 가죽 슈퍼 클래스 필드 및 클래스 B의 모든 코드 이 필드를 사용합니다. Sun's Java tutorial이이 문제에 대해 말할 수있다 : 자신의 유형이 다른 경우에도 클래스 내에서

, 슈퍼 클래스의 필드를 숨 깁니다 슈퍼 클래스 의 필드와 같은 이름을 가진 필드를. 하위 클래스에서 수퍼 클래스 의 필드는 간단한 이름으로 참조 할 수 없습니다. 대신, 필드는 다음 섹션에서 인 super을 통해 액세스되는 이어야합니다. 일반적으로 을 말하면 코드를 숨기기가 어렵 기 때문에 필드를 숨기지 않는 것이 좋습니다.

3

new B().getStaticProperty()A으로 범위가 지정되어 있으므로 A의 정적 속성을 반환하는 A에서 메서드를 호출하고 있습니다.

0

getStaticProperty()는 클래스 A에 정의 된 메서드입니다.이 메서드는 클래스 B에서 재정의되지 않으므로 클래스 A의 메서드가 사용됩니다. A는 어떤 식 으로든 B의 정적 속성을 '볼 수 없으므로 자체 값을 반환합니다.

1

함수는 Java에서는 가상이지만 클래스 멤버 (정적 또는 인스턴스)는 그렇지 않습니다. 따라서 B의 정의 staticProperty은 A의 정의를 가릴 수 있지만 무시하지는 않습니다. 당신이 제안으로

// in B 
String fromChild = staticProperty; // == "b" 
String fromParent = A.staticProperty; // == "a", was masked but not overridden 

있는 유일한 방법은, B에 정의 된 변수에 액세스 할 수있는가에 getter 함수를 정의하고 B에서 재정의하는 것입니다 얻을 수 있습니다.

+0

그래서 B가 A에서 getStaticProperty() 메소드를 상속 받았을 때 (그리고 결과적으로 B가 자신을 선언 한 것처럼)이 상속 된 메소드는 여전히 수퍼 클래스의 속성을 참조하고 있습니까? 회원 이름과 충돌이 있습니다. 아마도 B의 staticProperty가 다른 이름을 가진다면 상황이 더 쉽게 보일 것입니다. – Dan

1

이와 같은 상속 문제를 생각하면 new B()이 호출 될 때 어떤 일이 발생하는지 생각하는 것이 도움이 될 수 있습니다.B의 생성자가 실행될 때 수행하는 첫 번째 연산 (A의 생성자에 대한 명시 적 호출이 없기 때문에)은 super()입니다. 이 시점에서 A의 인스턴스가 만들어지고이 개체에서 getStaticProperty() 메서드는 A의 staticProperty을 명확하게 나타냅니다. B의 생성자 본문이 A의 생성자를 성공적으로 실행 한 후에 다시 실행되며 A의 생성자에 의해 인스턴스화 된 getStaticProperty() 메서드를 변경하거나 무시하지 않으므로 해당 메서드의 동작을 변경하지 않습니다.

처음에는 혼란 스러울 수도 있지만 다양한 상속 문제의 의미를 생각해 볼 때 유용 할 수 있습니다.

+0

이 질문에 대한 답변은 정말 잘 쓰여 있습니다. Shaun은 맞습니다. super에 대한 호출이 여기에 핵심입니다. –