gpt4 book ai didi

Scala:父类是否可以访问仅由子级定义的方法?

转载 作者:行者123 更新时间:2023-12-04 18:12:39 24 4
gpt4 key购买 nike

我有两个从抽象基类继承的案例类。我想在抽象基类上定义一些方法,这些方法在继承的case类上使用copy方法(并因此返回子类的实例。)是否可以使用self类型来做到这一点?

示例代码:

abstract class BaseClass(a: String, b: Int) {
this: case class => //not legal, but I'm looking for something similar

def doubleB(newB: Int) = this.copy(b = b * 2) //doesn't work because BaseClass has no copy
}

case class HasC(a: String, b: Int, c: Boolean) extends BaseClass(a, b) {
def doesStuffWithC(newC: Boolean) = {
...
}
}

case class HasD(a: String, b: Int, D: Double) extends BaseClass(a, b) {
def doesStuffWithD(newD: Double) = {
...
}
}

由于这个问题,我已经弄清楚了如何获得想要的结果:
How to use Scala's this typing, abstract types, etc. to implement a Self type?
但是它涉及到在BaseClass中添加一个makeCopy方法,并在每个子case类中调用复制来覆盖它,并且语法(尤其是Self类型)尤其令人困惑。使用Scala的内置自动键入功能可以做到这一点吗?

最佳答案

您无法做您想做的事情,因为copy需要知道所有可能的参数。因此,即使案例类是从Copyable继承的,也不是您需要的copy。另外,如果您要保持类型的笔直,则会因Scala缺少“MyType”而受挫。因此,您不能只扩展基类。但是,您可以添加一个抽象方法并键入批注:

abstract class BaseClass[C <: BaseClass[_]](a: String, b: Int) {
def setB(b0: Int): C
def doubleB(b0: Int) = setB(b0*2)
}
case class HasC(a: String, b: Int, c: Boolean) extends BaseClass[HasC](a,b) {
def setB(b0: Int) = this.copy(b = b0)
def doesStuffWithC(c0: Boolean) = doubleB(if (c0) b else -b).copy(c = c0)
}

然后您可以:
scala> HasC("fish",1,false).doesStuffWithC(true)
res47: HasC = HasC(fish,2,true)

如果您有很多共享功能仅依赖于复制 b的能力(很多方法或少数复杂方法),那么这项额外的工作将是值得的(也就是说,这解决了DRY问题)。相反,如果您想抽象 HasC和其他派生类,则可以使用 BaseClass[_]或添加另一个定义 setB(b0: Int): BaseBase的级别,或者干脆忘记类型参数化并将 BaseClass用作返回类型(但要意识到 HasC无法使用 BaseClass方法,并且保留其类型标识)。

关于Scala:父类是否可以访问仅由子级定义的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10304728/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com