찾다

 >  Q&A  >  본문

java继承中,为什么向上转型后无法运行子类中特有的方法?

看了这篇文章:
https://www.ibm.com/developerworks/cn/java/j-lo-polymorph/
有一些疑问。

class Person { 
 public String toString(){
    return "I'm a person."; 
 } 
 public void eat(){} 
 public void speak(){} 
    
 } 

 class Boy extends Person{ 
 public String toString(){ 
    return "I'm a boy"; 
     } 
 public void speak(){} 
 public void fight(){} 
 } 

 class Girl extends Person{ 
 public String toString(){ 
    return "I'm a girl"; 
     } 
 public void speak(){} 
 public void sing(){} 
 }
//最后这么用的话,
Person girl = new Girl(); 
girl.speak(); 

按照作者的说法,girl引用变量指向堆中的 Girl对象,所以运行的时候知道当前对象是Girl对象,找Girl的方法表,
找到后执行。这对于speak方法来说是行得通的。
但是如果这样呢:
girl.sing();
按照作者的说法,去Girl方法表找到sing方法,然后执行。
实际情况大家都知道有错误,编译不通过。
这中间肯定漏了点我不知道的什么?希望可以赐教。
换个方式问也就是:
当发生向上转型的时候,栈和堆中分别发生了什么?

怪我咯怪我咯2767일 전478

모든 응답(4)나는 대답할 것이다

  • PHPz

    PHPz2017-04-17 17:21:39

    소스 코드는 이렇게 생겼습니다. 아직 생략된 부분이 있습니다. 이제 코드가 이렇게 생겼으니
    Person girl = new Girl()
    girl을 넣지 마세요. .speak( )
    이 두 문장은 수업시간에 직접 호출하면 구조가 틀려요

    회신하다
    0
  • 黄舟

    黄舟2017-04-17 17:21:39

    호출할 수 있는 메서드를 결정하는 것은 변수가 가리키는 힙에 있는 개체의 실제 유형이 아니라 변수의 선언된 유형 입니다.

    당신을 좋아합니다:

    으아악

    girl의 선언 유형은 Person이고, Person에는 speak 메서드가 없으므로 오류가 보고됩니다. 이는 컴파일러가 보고한 컴파일 시간 오류입니다. 컴파일러는 girl이 어떤 유형으로 실행되는지 상관하지 않습니다.

    런타임 동안 가상 머신은 물론 girl에 의해 실행된 힙의 개체가 Girl 유형이라는 것을 알게 됩니다.

    컴파일러는 선언된 변수 유형에 따라 메소드 호출 가능 여부를 결정하는 이유는 무엇입니까? 그 이유 중 하나는 컴파일하는 동안 이 변수가 런타임에 어떤 유형의 개체에 바인딩되어 있는지 전혀 알 수 없기 때문입니다. 예:

    으아악

    이 예에서 p는 런타임까지 바인딩된 개체의 실제 유형을 확인할 수 없습니다.

    회신하다
    0
  • ringa_lee

    ringa_lee2017-04-17 17:21:39

    주제의 질문은 다형성 개념과 관련이 있습니다. 설명을 위해 주제의 예를 사용해 보겠습니다.

    주제별로 정의된 세 가지 클래스 Person, Girl, Boy를 사용한다고 가정합니다. 언제

    으아악

    객체 ps를 정의한 후 컴파일 시 해당 유형은 Person이지만 런타임 시 실제 유형은 Girl입니다.

    ps 개체를 사용할 때 프로그램은 그것이 Person이라는 것만 알고 Person에는 eatspeak의 두 가지 메서드만 있으므로 개체 멤버를 호출할 때 eatspeak 두 메서드만 호출합니다. 프로그램은 ps 개체의 실제 유형이 Girl인지 모르므로 Girl의 고유한 sing 메서드를 호출할 수 없습니다. 즉,

    으아악

    그러면 프로그램은 ps 객체의 실제 동적 유형이 Girl인지 알지 못하는데 왜 ps.speak();가 여전히 Girl에서 구현을 호출할 수 있습니까? 이것이 다형성이 하는 일입니다.

    하위 클래스를 가리키는 상위 클래스 포인터/참조의 경우 상위 클래스 메서드가 하위 클래스에서 재정의된 경우 이 메서드가 상위 클래스 포인터/참조를 통해 호출되면 컴파일러는 상위 클래스 포인터/참조를 추가합니다. 컴파일하는 동안 클래스 메서드 호출은 실제 유형의 메서드에 동적으로 바인딩됩니다. 하위 클래스에 의해 재정의되지 않은 메서드는 부모 클래스의 메서드에 정적으로 바인딩됩니다.

    이는 추상적인 관점에서 이해됩니다. 하위 수준 구현 방법은 특정 구현을 참조해야 하며, 이는 주제에서 제공하는 기사에서 더 명확하게 설명됩니다.

    회신하다
    0
  • 大家讲道理

    大家讲道理2017-04-17 17:21:39

    스택은 사람, 힙은 소녀, 사람 클래스는 노래 방법에 대한 참조가 없습니다.

    회신하다
    0
  • 취소회신하다