2014-12-17 5 views
1

나는 다음과 같은 코드가 있습니다스칼라 다형성

trait SuperX { 
val v: Int 
} 

class SubY(val v: Int, var z: SuperX) extends SuperX 

class SubZ(val v: Int) extends SuperX 

을하고 난 다음

var test = new SubY(1, new SubZ(-1)) 

로 작성하는 경우 나는이

var test: SuperX = new SubY(1, new SubZ(-1)) 
println(test.z.v) 

수없는 이유를 이해하지 않습니다 I 할 수 없다

test = test.z 

저는 스칼라를 처음 접해 보았습니다. 그래서 어떤 것들은 상당히 혼란 스럽습니다. 특성 대신 인터페이스를 사용하여 Java에서 가능하다는 것을 알고 있습니다.

도움 주셔서 감사합니다.

+0

호기심에서 벗어나서 Java로 어떻게 할 것입니까? – Dimitri

답변

5

들입니다

test: SubY = [email protected] 

SuperX로 선언 컴파일러는 testSuperX입니다. 그리고 SuperX 유형은이 특정 인스턴스가 수행하는 경우에도 z을 가질 수 있습니다.

당신은 쓸 때 :

var test = new SubY(1, new SubZ(-1)) 

test의 종류가 너무 test.z 괜찮 호출 z을 가지고있는 SubY로 추정된다.

+0

어떻게하면 test = test.z라고 말할 수있는 프로그램의 구조를 바꿀 수 있습니까? 후자의 경우 test.z를 호출 할 수는 있지만 테스트 유형은 SubY입니다. 이상적으로는 테스트가 SuperX 유형이되고 싶습니다. SubY 또는 SubZ 중 하나의 서브 클래스에 할당 할 가능성이 있습니다. 할당이 성공하면 일부 필드 (SubY의 경우에만 z, SubY의 경우에만 발생)를 호출하려고합니다. – Robin64

+0

형식 테스트를 사용하지 않고는 작업을 수행 할 수 없습니다. 'SuperX'는'z'가없는'SubZ '일 수도 있습니다. 그래서'Sub.'라는 것을 먼저 확인하지 않고'test.z' ('SuperX' 타입을 가졌 으면)를 호출 할 수 없습니다. 예를 들어,'SubY '에 대한'test' 패턴 매칭에 의한 것이지만, 여전히'SubZ' 인 경우에 당신을 강제로 처리 할 것입니다. –

+0

좋아요, 그렇지만 그렇게 할 수있는 다형성의 목적이 아닌가요? 나는 자바에서 이런 식으로 할 수있을 것이다. 그래서 스칼라의 방식이 나에게 너무 혼란 스럽습니다. – Robin64

1

REPL은 결과 유형 호출 한 후에 무엇을 말할 것이다 : 이것은 당신이 예상대로 추정 형 참조 SubY하지 SuperX 것을 보여줍니다

scala> var test = new SubY(1, new SubZ(-1)) 

. Scala는 타입을 제공하지 않으면 유추 된 타입을 상속받습니다.

var test: SuperX = new SubY(1, new SubZ(-1)) 

당신은 명시 적으로 얘기하고 있습니다 : 첫 번째 예는 명시 적 그러므로 당신이 호출 할 수있는 유일한 방법과 변수는이 라인에 SubY