Java는 다른 객체에서 부모의 재정의 메소드를 호출 할 수 있지만 하위 유형은 없습니까?
-
06-07-2019 - |
문제
다음은 Java 코드가 작동합니다
class Cup {
public String sayColor() {
return "i have a color .";
}
}
class TCup extends Cup{
public String sayColor(){
System.out.println(super.getClass().getName());
return super.sayColor()+"color is tee green.";
}
}
class MyTCup extends TCup {
public String sayColor(){
System.out.println(super.getClass().getName());
return super.sayColor()+"but brushed to red now!";
}
}
class Test {
public static void main(String[] args) {
Cup c = new MyTCup();
System.out.print(c.sayColor());
}
}
테스트 클래스 인쇄를 실행합니다
MyTCup
MyTCup
i have a color .color is tee green.but brushed to red now!
질문 1 : 런타임에서 객체 C 유형은 MyTcup이지만 항상 슈퍼 메소드를 호출 할 수 있습니다. 객체를 초기화 한 후 Mytcup 내에서 메모리에 메소드 스택이 있습니까? 그런 다음 코드와 같이 런타임에 호출 할 수 있습니까?
질문 2 : 다른 개체에서 수퍼 방법을 호출 할 방법이 없습니다. 아시다시피, C ++는 언제든지 상위 메소드를 호출하기 위해 캐스트 할 수 있습니다. Java에서 왜 다른가요?
해결책
캡슐화를 위반하는 다른 객체에서 슈퍼 메소드를 호출 할 수 없습니다. 요점은 객체가 재정의 메소드가하는 일을 제어한다는 것입니다. 예를 들어, 컬렉션을 무시할 수 있습니다 add
방법 특정 상황에서 예외를 던지는 방법이므로 컬렉션에 "유효한"항목 만 추가 될 수 있습니다. 발신자가 캐스트로 우회 할 수 있다면 무의미합니다!
물체가 호출하는 유일한 이유 super.foo()
자체는 부모 구현을 사용하여 하나의 호출을 구현할 수 있도록하는 것입니다. 클래스의 코드에 달려있어서 현명하게 만 수행 할 수 있습니다. 다시, 컬렉션이 반복되는 경우 추가 수집 예제를 가져옵니다. add
가져야 할 것입니다 약간 검증 된 항목을 컬렉션에 추가하는 방법으로 super.add()
.
동일한 이유와 같은 이유로 뿐 조부모 구현이 아닌 부모 구현에 전화하십시오. super.foo()
유효하지만 super.super.foo()
그렇지 않습니다.
다른 팁
1:
귀하의 질문은 명확하지 않습니다. "코드처럼 런타임에 전화를 걸어"는 무엇을 의미합니까? 인스턴스 C가 슈퍼 클래스가 무엇인지 알고있는 경우, 클래스 계층 구조는 메모리에 저장되며 VM에서 액세스 할 수 있습니다.
2:
Java는 실제로 부모에게 인스턴스를 캐스팅 할 수 있습니다. 인스턴스에서 메소드를 호출하는 것은 항상 컴파일 타임 클래스가 아니라 인스턴스의 실제 클래스를 사용하는 것입니다. 즉, Java의 모든 방법은 C ++에서 "가상"이라고 불리는 것입니다. 이것이 내가 모르는 이유를 결정한 이유.
편집하다: 실제로 Jon Skeet은 왜 하위 클래스의 인스턴스에서 슈퍼 클래스의 메소드를 호출 할 수 없는지 매우 훌륭하게 설명합니다.
서브 클래스에서 새 헬퍼 메소드를 정의하여 원하는 것에 따라 슈퍼 방법을 호출 할 수있는 원본을 무시하지 않도록 할 수 있습니다.
실제로 할 수는 있지만 방법론을 사용해야하므로 코드에서만 작동합니다.
슈퍼 클래스에서는 다음과 같이 메소드에 매개 변수 "클래스"를 추가하십시오.
public String sayColor(Class classFilter){...
이제 모든 재정의에서 현재 하위 클래스가 지정된 필터 중 하나인지 확인하십시오.
if(TCup.class!=classFilter)return super.sayColor(classFilter);
return "some text for TCup only";
나는 독점적 인 방식으로 코딩했다. 더 많은 매개 변수를 추가하거나 NULL과 비교할 수 있으므로 Super Classment와 결과를 가입하고 창의성을 사용할 수 있습니다 :)