Сохранение аргументов, переданных конструктору суперкласса - PullRequest
1 голос
/ 23 декабря 2011

В Scala нельзя вызывать методы для текущего экземпляра при вызове конструктора суперкласса. Таким образом, нет возможности для вызова метода, который запомнит значение, которое он возвращает, в текущем экземпляре. Как я могу сохранить аргументы, выданные для конструктора суперкласса, при этом используя наследование, в отличие от композиции и без изменения исходного кода класса, от которого я наследую?

Ответы [ 4 ]

2 голосов
/ 17 января 2012

В Scala 2.8 и выше используйте раннее определение:

class Foo(arg1: Type1, arg2: Type2) extends {
   val arg3 = new Type3(arg1)
   val arg4 = new Type4(arg2)
} with Bar(arg3, arg4)

Это работает, даже если Bar является классом, а не чертой.

2 голосов
/ 23 декабря 2011

Вы также можете использовать

class Foo(arg1: Type1, arg2: Type 2)(
  implicit computed: Hidden[(Type3,Type4)] = (new Type3(arg1), new Type4(arg2))
) extends Bar(computed._1, computed._2) { }

учитывая

private[mypackage] class Hidden[A](val value: A) { }
implicit def i_can_hide_things[A](a: A) = new Hidden(a)
implicit def i_can_find_things[A](ha: Hidden[A]) = ha.value
1 голос
/ 23 декабря 2011

Создание объекта-компаньона с помощью фабричного метода. Метод фабрики вычисляет аргументы для передачи их конструктору суперкласса. Но, конечно, это не происходит напрямую - не может. Вместо этого он вызывает ваш основной конструктор, который вы можете сделать приватным, например:

class C private (private val superclassArg: ArgType) extends Super(superclassArg) { ... }

К сожалению, это решение не очень композиционно, потому что оно не позволяет вам наследовать от C. Если сделать конструктор C общедоступным, это все равно потребует дублирования кода, и вы можете забыть предварительно обработать аргумент конструктора. Я полагаю, это зависит от того, считаете ли вы, что для подклассов C всегда необходимо предварительно обработать аргумент таким образом.

0 голосов
/ 23 декабря 2011

Включите другой класс (здесь MemoBar) в иерархию наследования, например:

class Foo(arg1: Type1, arg2: Type2) extends MemoBar(new Type3(arg1), new Type4(arg2)) {
}

class MemoBar(protected val arg3: Type3, arg4: Type4) extends Bar(arg3, arg4) {}

Тогда ваши arg3 и arg4 будут сохранены и видимы только для подклассов MemoBar(в этом случае просто Foo, но, конечно, вы можете повторно использовать MemoBar, если вы столкнулись с той же проблемой с Bar снова).

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