2012-01-12 2 views
1

우리는 우리가 다음의 두 가지 클래스가 있다고 가정하자 그들에게 두 경우 클래스를 만들기스칼라 아이의 경우 클래스 매개 변수 이름 충돌

abstract case class MyParent(param: Int) { 
    // ... 
} 

case class MyChild(param: Int) extends MyParent(param: Int) { 
    // ...   ^^^^^      ^^^^^ 
} 

는 말한다, 이는 모두 param 사용 장소에 오류가 발생 부모 클래스의 값을 무시하는 override 수정자가 필요합니다. 이것은 이상하게 보입니다. 왜 다른 param 이름을 만들어야합니까? 왜 이런 것들의 순서가 적용됩니까? 이익은 어디에 있습니까?

답변

7

다른 케이스 클래스에서 케이스 클래스를 파생해서는 안됩니다!

scala> case class Foo(foo: String) 
defined class Foo 

scala> case class Bar(override val foo: String) extends Foo(foo) 
<console>:9: warning: case class `class Bar' has case ancestor `class Foo'. Case-to-case inheritance has potentially dangerous bugs which are unlikely to be fixed. You are strongly encouraged to instead use extractors to pattern match on non-leaf nodes. 
1

그것에 대한 빠른 수정이

abstract case class MyParent(param: Int) { 
    println("Form parent : " + param) 
} 

case class MyChild(override val param: Int) extends MyParent(param) { 
    println("Form child : " + param) 
} 

val c = MyChild(10); 

이 자바처럼되지 않습니다 사실이

>> From parent : 10 
>> From child : 10 

extends MyParent()가 발생합니다 할 것입니다. 이 방법은 MyChildMyParent까지 확장하고 먼저 후자의 슈퍼 생성자를 호출하는 방법입니다.

1

이익은 다음과 같습니다

가 REPL이 시도는 스칼라 -deprecation 시작?

간단히 말해서 너무 유용하지 않은 특별한 경우가 없습니다. paramcase class MyChild(param: Int)은 클래스 멤버이며 생성자 매개 변수이므로 조상 중 하나가 이미 추상이 아닌 param 멤버를 가지고 있으므로 재정의해야합니다. 스칼라에서는 다른 모든 곳을 재정의 할 때 override 키워드가 필요하기 때문에 여기에도 필요합니다.

1

제한된 Scala 지식이있는 한 대개 대/소문자 데이터 형식 및 패턴 일치에 대개 사례 클래스가 사용됩니다. 따라서 "자식 클래스"를 만드는 대신 에 "부모"클래스 인이 포함 된 클래스를 만들어야합니다.

> case class MyParent(param: Int) 
defined class MyParent 

> case class MyChild(param: Int, parent: MyParent) 
defined class MyChild 

> def foo(c: MyChild) = c match { 
    case MyChild(p, MyParent(p2)) => println("p: " + p + ", p2 " + p2) 
    } 
foo: (c: MyChild)Unit 

> foo(MyChild(3, MyParent(4))) 
p: 3, p2 4