将依赖对象传递给 Scala 中的父构造函数

发布于 2024-09-01 20:34:54 字数 516 浏览 1 评论 0原文

假设我有以下类层次结构:

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))

有干净的方法来做到这一点吗?

Suppose I have the following class heirarchy:

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

class BaseClass(b:B, c:C)

Now I want to implement a subclass of BaseClass, which is given an instance of A, and constructs instances of B and C, which it passes to its superclass constructor.

If I could use arbitrary expressions, I'd do something like this:

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

Because the second argument to the parent constructor depends on the value of the first argument, though, I can't see any way to do this, without using a factory function, or a gratuitous hack, such as :

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

Is there clean way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那请放手 2024-09-08 20:34:54

处理这种情况的最佳方法可能是在要编写的 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)。

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

Probably the best way to handle this sort of situation is by writing a factory method in the companion object for the subclass of BaseClass you want to write.

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)
    }
}

You can make any of those constructor parameters into fields without affecting anything (by prefixing with val, if you're not familiar with that syntax):

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)
    }
}

Now new instances of SBC can be created with this sort of expression: SBC(aValue) (regardless of whether the vals are used).

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文