Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala case类和继承:如何提供不同的行为_Scala_Case Class_Traits_Self Type - Fatal编程技术网

Scala case类和继承:如何提供不同的行为

Scala case类和继承:如何提供不同的行为,scala,case-class,traits,self-type,Scala,Case Class,Traits,Self Type,情况: trait Operation { def something: Double } trait OperationPlus { this: A => override def something: Double = x + y } trait OperationMinus { this: A => override def something: Double = x - y } case class A(x: Double, y: Double) { this:

情况:

trait Operation {
def something: Double 
}

trait OperationPlus { this: A =>
override def something: Double = x + y
}
trait OperationMinus { this: A =>
    override def something: Double = x - y
}

case class A(x: Double, y: Double) { this:  Operation =>
}

val a = new A(1.0, 2.0) with OperationPlus
  println(a.something)
错误:

class A cannot be instantiated because it does not conform to its self-type A with Operation
而且,我不能实例化一个

我尝试了多种不同的方法,但都没有提供我想要的。我不想使用case类继承,也不想放弃case类,理想情况下,trait/self-types/其他东西应该可以做到这一点。有什么想法吗

更新 首选解决方案

 trait Operation { this: A =>
 def something: Double 
 }

 trait OperationPlus extends Operation { this: A =>
   override def something: Double = x + y
 }
 trait OperationMinus extends Operation { this: A =>
     override def something: Double = x - y
 }

 abstract case class A(val x: Double, val y: Double) extends Operation

 val a = new A(1.0, 2.0) with OperationPlus
 println(a.something)

 val b = new A(1.0, 2.0) with OperationMinus
 println(b.something)
可能的解决办法1:

trait Operation {
  def x:Double 
  def y:Double
  def something: Double 
}

trait OperationPlus extends Operation {
  override def something: Double = x + y
}
trait OperationMinus extends Operation {
      override def something: Double = x - y
}

abstract case class A(val x: Double, val y: Double) extends Operation 
通过使用常规类,简单的特征继承和实际值中的自我类型可以定义它并动态提供行为

不幸的是,我必须重新定义trait中的字段。我想这是一个公平的妥协。我想知道是否有人知道另一种方法


谢谢

不确定您的用例,但是如果您想让它工作,您需要像这样定义class
A

abstract case class A(x: Double, y: Double) extends Operation

但我不认为这是一种非常惯用的用例类方法。它们主要用作数据容器,通常不包含任何行为。(也许你可以告诉一些关于你想用这个实现的事情的更多信息)

不确定你的用例,但是如果你想让它工作,你需要像这样定义class
A

abstract case class A(x: Double, y: Double) extends Operation

但我不认为这是一种非常惯用的用例类方法。它们主要用作数据容器,通常不包含任何行为。(也许你可以告诉我更多关于你想通过这个实现的事情的信息)

首先,你应该:

trait OperationPlus extends Operation
trait OperationMinus extends Operation
其次,您不能将
A
定义为case类,因为这会自动定义伴生对象上的
apply
方法,其中调用
newa
(带参数)。由于错误的自我类型(您看到的错误),此调用失败

卸下
外壳
。如果需要模式匹配,请自己定义一个提取器(不适用地实现
):


首先,你应该:

trait OperationPlus extends Operation
trait OperationMinus extends Operation
其次,您不能将
A
定义为case类,因为这会自动定义伴生对象上的
apply
方法,其中调用
newa
(带参数)。由于错误的自我类型(您看到的错误),此调用失败

卸下
外壳
。如果需要模式匹配,请自己定义一个提取器(不适用地实现
):


谢谢@tenshi,如果我将案例类抽象化,我将无法实例化它。我试图做的是一个经典的面向对象父类,每个子类定义一个方法。然而,这些方法可以被不同的层次结构重用,所以我想将其作为基本特征。我就是找不到如何提取它。@fracca您仍然可以通过混合一些操作来实例化它:
newa(1.0,2.0)和operation减号
。但是在您的示例方法
中,有些东西是抽象的,所以您需要定义它或使整个类抽象。或者,您可以在类
A
中直接扩展
operation减号
OperationPlus
,而不将其声明为抽象。抽象案例类有效地保留了案例类加行为混合的优点。但是,因为something操作是基于A定义的,所以我需要重新定义字段x和y。谢谢@tenshi,如果我将case类抽象化,我将无法实例化它。我试图做的是一个经典的面向对象父类,每个子类定义一个方法。然而,这些方法可以被不同的层次结构重用,所以我想将其作为基本特征。我就是找不到如何提取它。@fracca您仍然可以通过混合一些操作来实例化它:
newa(1.0,2.0)和operation减号
。但是在您的示例方法
中,有些东西是抽象的,所以您需要定义它或使整个类抽象。或者,您可以在类
A
中直接扩展
operation减号
OperationPlus
,而不将其声明为抽象。抽象案例类有效地保留了案例类加行为混合的优点。但是,因为something操作是基于A定义的,所以我需要重新定义字段x和y。