2014-04-17 3 views
1

"test"를 출력해야하는 원래 메쏘드 대신에 override 메소드에서 문자열을 출력하는 이유는 무엇입니까? 난 이미 parent 식별자가 단순히 this 객체,이 객체가 런타임에 무엇이든에 대한 포인터의 또 다른 이름 당신의 예에서 방법을스칼라에서 오버라이드 된 호출 메쏘드

class myClass { 
    parent=> 
    def method(a:Int):String={ 
     "test" 
    } 
    def run={ 
     println(parent.method(1)) 
    } 
} 

val testClass=new myClass { 
    override def method(a:Int):String={ 
      "substring" 
    } 
} 

답변

4

전화를 자신과 사용 부모를 가리 키도록 부모를 사용합니다. 스칼라와 자바 (일반적으로 JVM)에서 객체에 대한 메소드를 호출하는 규칙은 객체의 런타임 유형에서 오버라이드 된 메소드가 호출된다는 것입니다. JVM은 객체 유형과 메소드 이름을 특정 구현과 연결하는 virtual function tables을 사용합니다. 이것은 C++과 달리 오브젝트 값 (포인터 또는 참조가 아님)에서 메소드를 호출하면 메소드가 해당 오브젝트의 컴파일 타임 유형에서 해석됩니다.

예를 들어, 스칼라 당신은 할 수 :

스칼라 컴파일러의 관점에서
val compileTimeVar: myClass = new myClass { override def method(a: Int) = "substring" } 

, compileTimeVar는 유형 myClass 있습니다. 그러나 런타임 형식은 xxx$anon$1과 같이 내부적으로 표시되는 이름없는 형식이며이 익명 형식은 method을 재정의합니다. 콜링 : 그것은 그 실행시의 형태로 존재하는 경우

compileTimeVar.method 

항상 오버라이드 (override) 된 메소드를 호출 - 그것은 "substring"를 반환합니다.

소위 self 포인터가 손실 런타임 타입 정보 객체를 변수에 할당 다르지 않습니다 - 당신의 코드는 다음에 해당합니다 :

class myClass { 
    def parent: myClass = this 
    def method(a: Int) = "test" 
    def run = println(parent.method(1)) 
} 

은 당신이 정말로 정의 method를 호출 run을 원하는 경우 myClass에서 무엇이 우선 적용 되든간에 다음을 수행하십시오.

class myClass { 
    private def privateMethod(a: Int) = "test" 
    def method(a: Int) = privateMethod(a) 
    def run = println(this.privateMethod(1)) 
} 
관련 문제