Передача зависимых объектов в родительский конструктор в Scala - PullRequest
2 голосов
/ 15 мая 2010

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

class A()
class B(a:A)
class C(b:B)

class BaseClass(b:B, c:C)

Теперь я хочу реализовать подкласс BaseClass, который получает экземпляр A и создает экземпляры B и C, которые он передает своему конструктору суперкласса.

Если бы я мог использовать произвольные выражения, я бы сделал что-то вроде этого:

b = new B(a)
c = new C(b)
super(b, c)

Поскольку второй аргумент родительского конструктора зависит от значения первого аргумента, я не вижу никакого способа сделать это без использования фабричной функции или безвозмездного хака, такого как:

class IntermediateSubclass(b:B) extends BaseClass(b, new C(b))
class RealSubclass(a:A) extends IntermediateSubclass(new B(a))

Есть ли чистый способ сделать это?

1 Ответ

5 голосов
/ 16 мая 2010

Вероятно, лучший способ справиться с подобной ситуацией - написать фабричный метод в объекте-компаньоне для подкласса BaseClass, который вы хотите написать.

class A()
class B(a:A)
class C(b:B)

class BaseClass(b:B, c:C)

class SBC private (a: A, b: B, c: C)
extends BaseClass(b, c)

object SBC
{
    def
    apply(a: A): SBC = {
        val b = new B(a)
        val c = new C(b)
        new SBC(a, b, c)
    }
}

Вы можете превратить любой из этих параметров конструктора в поля, не влияя ни на что (префиксом val, если вы не знакомы с этим синтаксисом):

class A()
class B(val a: A)
class C(val b: B)

class BaseClass(val b: B, val c: C)

class SBC private (val a: A, b: B, c: C)
extends BaseClass(b, c)

object SBC
{
    def
    apply(a: A): SBC = {
        val b = new B(a)
        val c = new C(b)
        new SBC(a, b, c)
    }
}

Теперь можно создавать новые экземпляры SBC с таким выражением: SBC(aValue) (независимо от того, используются ли val s).

scala> val a1 = new A
a1: A = A@14a8f44

scala> val sbc1 = SBC(a1)
sbc1: SBC = SBC@7d8bb

scala> sbc1.a
res0: A = A@14a8f44

scala> sbc1.b
res1: B = B@c7272

scala> sbc1.c
res2: C = C@178743b
...