이 일반적인 경우 자바 작업에서 다형성을 수행하는 방법 (매개 변수 방법)?

CandyCrusher :

나는 일반적인 경우에 대한 코드를 가지고 :

public class A {
    public String show(A obj) {
        return ("A and A");
    }
}

public class B extends A {
    public String show(B obj) {
        return ("B and B");
    }

    public String show(A obj) {
        return ("B and A");
    }
}

public class C extends B {

}

public class Test {
    public static void main(String[] args) {
        A a = new B();
        B b = new B();
        C c = new C();

        System.out.println("1--" + a.show(b));
        System.out.println("2--" + a.show(c));     
    }
}

그 결과는 다음과 같습니다

1--B and A
2--B and A

나는 자바 내림차순에서 우선 순위 체인이 알고 :

this.show(O), super.show(O), this.show((super)O), super.show((super)O)

나의 이해는 다음과 같습니다 :

이 코드에서 :

A a = new B()

업 캐스팅 발생합니다. A는 부모 클래스 참조이며, B는 아이의 부모 클래스의 참조입니다. 코드를 컴파일하고 실행하면, 아이의 부모 클래스 참조는 방법을 선택하는 방법을 결정합니다. 이 경우, show(A)클래스 B가 선택된다.

부모 클래스 정의에 포함되어야 선택에있어서 다형성 충족해야하는 요구 사항도 있습니다.

누군가가 그 결과에 대한 자세한 설명 표시를 줄 수 있을까요?

TiiJ7 :

당신은 결과를 얻을 이유를 얻기 위해 B and A컴파일 및 실행 : 두 번이 2 개 부분이 있다는 것을 알 필요가있다.

편집

문을 발생하는 경우 a.show(b), 컴파일러는 다음과 같은 기본 단계를 수행합니다

  1. 메소드가 호출 (되는 객체 봐 a)와 선언 된 유형을 얻을. 이 유형이다 A.
  2. 클래스 A와 그 슈퍼 타입의 모든 명명 된 모든 메소드의 목록을 작성 show. 컴파일러는 발견 할 것이다 show(A). 그것은 어떤 방법 보지 않는 BC.
  3. 발견 방법의 목록에서 가장 매개 변수 (일치하는지 하나를 선택 b) (있는 경우). show(A)받아 b이 방법이 선택되도록.

같은 일이 당신이 전달하는 두 번째 통화에 발생합니다 c. 처음 두 단계는 동일하고, 세 번째 단계는 다시 찾을 것 show(A)하나가 있기 때문에, 또한 매개 변수를 일치합니다 c. 그래서, 통화의 모두에 대해, 나머지 과정은 동일합니다.

컴파일러가 무엇을 필요로하는지 방법을 파악하면, 그것은 바이트 코드 명령어를 생성합니다 invokevirtual, 그리고 해결 방법을 넣어 show(A)(오프닝 이클립스에 표시된대로 전화를해야 하나 .class) :

invokevirtual org.example.A.show(org.example.A) : java.lang.String [35]

실행 시간

런타임은, 때 결국에 도달 invokevirtual또한 몇 단계를 수행 할 필요가있다.

  1. 이다 (그때까지 스택에 이미) 메소드가 호출되는 객체를 가져옵니다 a.
  2. 실제 봐 런타임 이 객체의 유형입니다. 이후 a = new B(),이 유형입니다 B.
  3. 에보고 B하고 방법을 찾아보십시오 show(A). 이 방법은 이후 발견되는 B재정의 그것. 이 경우이 아니었다 경우, 슈퍼 클래스 (에서 보는 것 AObject같은 방법을 찾을 때까지). 단지 고려하는 것이 중요하다 show(A)예를 들어, 그래서 방법을. show(B)에서는 B고려되지 않습니다.
  4. 런타임은 이제 방법 호출 show(A)에서을 B을주는 String B and A결과로.

이에 대한 자세한 내용은 주어진다 을위한 사양invokevirtual :

확인 된 방법은 서명 다형성 (§2.9)되지 않으면, invokevirtual 명령어는 다음 진행한다.

C는 objectref도의 클래스하자. 실제 방법은 다음 조회 절차에 의해 선택되고 호출 될 :

C는 오버라이드 (§5.4.5)이 해결 방법은 다음 m 호출 될 메소드하는 인스턴스 메소드 m에 대한 선언 및 조회 절차가 종료를 포함하는 경우.

C 수퍼 클래스가있는 경우, 그렇지 않으면, 동일한 조회 절차 C의 직접 수퍼를 사용하여 반복적으로 수행된다; 호출되어야 할 메소드가이 조회 절차의 재귀 호출의 결과이다.

그렇지 않고 AbstractMethodError가 발생합니다.

귀하의 예를 들어, objectref이다 a, 그 클래스입니다 B및 해결 방법은에서이다 invokevirtual( show(A)에서 A)


TL은 : DR은 - 컴파일 시간, 실행 어디에서 호출하는 결정 호출에 어떤 방법을 결정합니다.

추천

출처http://43.154.161.224:23101/article/api/json?id=192196&siteId=1