Scala与trait对比Java代码中的抽象类

时间:2018-07-02 16:03:51

标签: java scala traits scala-java-interop companion-object

我们可以为抽象类定义Scala伴随对象:

object CompanionAbstractClass {
  def newInstance():CompanionAbstractClass = CACChild("companion abstract class")
}
//sealed trait TestQ{
sealed abstract class CompanionAbstractClass{
  val name:String
}
case class CACChild(name:String) extends CompanionAbstractClass

从Scala代码中,我可以将其用作:

val q1 = CompanionAbstractClass.newInstance.name

从Java代码开始,它可以用作:

CompanionAbstractClass.newInstance().name();

为了在Scala中更好地合成,我们更喜欢使用特征:

object CompanionTrait {
  def newInstance():CompanionTrait = CTChild("companion trait")
}
sealed trait CompanionTrait {
  val name:String
}
case class CTChild(name:String) extends CompanionTrait

可以从Scala中以与以前类似的方式使用它:

CompanionTrait.newInstance().name

但是现在从Java中,我不能以与以下方式相同的方式调用它:

CompanionTrait.newInstance().name();

我只能通过以下方式做到这一点

CompanionTrait$.MODULE$.newInstance().name();

要改善先前的语法并摆脱“ $”,我可以在Scala或Java中创建包装器(这对我的选择不利):

object CompanionTraitFactory {
  def newInstance():CompanionTrait = CompanionTrait.newInstance()
}

现在从Java中我也可以将其用作:

CompanionTraitFactory.newInstance().name();

请您解释一下,为什么为特征定义了一个伴随对象,为什么我不能以这种方式从Java使用它,对于抽象类(CompanionAbstractClass情况),如何使用它呢? ),甚至是通常的单例(CompanionTraitFactory情况)。伙计们,我或多或少地了解了scala特性和抽象类之间的区别。我想了解,为什么以这种方式实施,并且将来有可能在Scala中得到支持

1 个答案:

答案 0 :(得分:2)

在可行的情况下,您正在调用添加到抽象类中的静态转发器。您以前不习惯在界面上进行静态转发,但在2.12中确实如此。