2012-09-07 3 views
3

그냥 수행 할 수 있고 할 수없는 것을 확인하기 위해 static 및 상속을 사용하여 방금 놀았습니다. 정적 메서드를 덮어 쓸 수 없다는 것을 전에 읽었습니다. 단순히 숨길 수 있습니다. 그래서 정적 멤버에게 적용되는 것을 확인하려고했습니다. 내가 객체에서 호출 X를 인쇄 모든 것이 예상대로 갔을 때 이제예기치 않은 상속 정적 멤버의 동작

public class ParentClass { 
    public static String x; 
    { x = "In ParentClass"; } 
} 

public class ChildClass extends ParentClass { 
    { x = "In ChildClass"; } 
} 

: 여기에 몇 가지 간단한 테스트 코드

: 자식 클래스 객체에서 x와 심지어 사소한 전화

ParentClass parentClassReference = new ParentClass(); 
System.out.println(parentClassReference.x); // prints: "In ParentClass" 

parentClassReference = new ChildClass(); 
System.out.println(parentClassReference.x); // prints: "In ChildClass" 

ChildClass childClassReference = new ChildClass(); 
System.out.println(childClassReference.x); // prints: "In ChildClass" 

나는 정적 멤버를 호출 할 때 그것을 할 가정처럼 지금, 그것은 도착 이상한 :

System.out.println(ChildClass.x); // prints: "In ChildClass" (Ok, so far.) 
System.out.println(ParentClass.x); // prints: "In ChildClass" (This is unexpected.) 

이 동작에 대한 설명이 없습니다. 컨텍스트에서 Overriding vs. Hiding (Code Ranch) 개체를 통한 호출이 예상대로 작동하지 않아야하지만 클래스 이름을 통한 호출이 더 잘 수행되어야합니다.

혼란 스럽습니다. 누가 도와 드릴까요?

답변

4

귀하의 코드는 입니다. 매우 이상한 ... 결과는 정확히 예상대로입니다. 단지 x 변수가 여기에있다

  • :

    당신은 세 가지를 이해할 필요가있다. 당신이 ChildClass.x 또는 ParentClass.x로 참조 여부를 참조를 통해 정적 멤버 를 참조 할 때,이 같은 변수

  • 의 컴파일러는 모든 기준의 가치를 보지 않고, 정적 참조로 변환합니다. 따라서 childClassReference.xChildClass.x과 동일하며 실제로는 ParentClass.x으로 컴파일됩니다. 좋은 IDE는 이런 종류의 일을 경고합니다. 혼란스러운 코드를 만들어냅니다.
  • 값을 x으로 설정하는 코드는 생성자 호출을 기반으로 만 실행됩니다. 기본적으로는 동등의 :

    public class ParentClass { 
        public static String x; 
        public ParentClass() { 
         x = "In ParentClass"; 
        } 
    } 
    
    public class ChildClass extends ParentClass { 
        public ChildClass() { 
         x = "In ChildClass"; 
        } 
    } 
    

기본적으로 정적 멤버를 통해 다형성의 어떤 종류를 달성하려고해서는 안된다. 그것은 작동하지 않으며, 그것을 시도가 행복하게 끝나지 않을 것입니다.

+0

좋아, 이제는 내가 염두에 두었던 구조를 보았습니다. 내 IDE는 실제로 그것에 대해 경고했지만 내가 말했듯이 : 나는 무엇이 일어나는지보기 위해 놀고있었습니다. – nfs

+1

+1 IMHO 절대 생성자 (또는 초기화 프로그램 블록)에서 정적 필드를 설정하는 것이 좋습니다. –