加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:父类有没有办法访问仅由子节点定义的方法?

发布时间:2020-12-16 09:57:19 所属栏目:安全 来源:网络整理
导读:我有两个从抽象基类继承的case类.我想在抽象基类上定义一些方法,这些方法在继承case类上使用复制方法(因此返回子类的实例.)有没有办法使用self类型? 示例代码: abstract class BaseClass(a: String,b: Int) { this: case class = //not legal,but I'm look
我有两个从抽象基类继承的case类.我想在抽象基类上定义一些方法,这些方法在继承case类上使用复制方法(因此返回子类的实例.)有没有办法使用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,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方法,并通过在每个子案例类中调用复制来覆盖它,并且语法(特别是对于Self类型)相当混乱.有没有办法用Scala的内置自键型来做到这一点?

解决方法

你无法做你想做的事,因为副本需要知道所有可能的参数.因此,即使从Copyable继承的case类,它也不是你需要的副本.此外,如果你要保持这些类型,你会被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,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方法并且仍然保留其类型标识).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读