Конфликт имени параметра класса дочернего случая Scala с именем параметра родительского класса наблюдения - PullRequest
1 голос
/ 12 января 2012

Предположим, у нас есть два следующих класса:

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

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

Создание обоих классов case привело к ошибке в обоих param местах использования, что говорит о том, что ему нужен модификатор overrideпереопределит значение из родительского класса.Это выглядит странно для меня ... почему я должен придумывать здесь другие имена параметров ... почему этот порядок вещей навязан?Где прибыль?

Ответы [ 4 ]

7 голосов
/ 12 января 2012

Вы никогда не должны получать класс case из другого класса case!

Попробуйте это в REPL, начинающемся с scala -deprecation :

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 голос
/ 12 января 2012

Что касается моего ограниченного знания 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
1 голос
/ 12 января 2012

Где прибыль?

Просто не слишком полезный особый случай.param в case class MyChild(param: Int) является членом класса, а также параметром конструктора, поэтому один из предков уже имеет (неабстрактный) член param, его необходимо переопределить.И Scala требует ключевое слово override при переопределении везде, поэтому оно требует и здесь.

1 голос
/ 12 января 2012

Быстрое решение для этого состоит в том, чтобы сделать это

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() не похож на Java. Это способ сказать MyChild extends MyParent и вызвать сначала супер-конструктор последнего.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...