2
votes

We can define Scala companion object for an abstract class:

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

From Scala code, I can use it as:

val q1 = CompanionAbstractClass.newInstance.name

From Java code, it can be used as:

CompanionAbstractClass.newInstance().name();

For better composition in Scala we prefer to use traits:

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

From Scala it can be used in a similar way as previously:

CompanionTrait.newInstance().name

But now from Java I cannot invoke it in the same way as:

CompanionTrait.newInstance().name();

I can do it only via:

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

To improve the previous syntax and get rid of this "$" I can create a wrapper in Scala or in Java (which is not good from my optionion):

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

Now from Java I can use it also as:

CompanionTraitFactory.newInstance().name();

Can you please explain, why in case a companion object is defined for a trait, I cannot use it from Java in the ways, how it can be used when it is defined either for abstract class (CompanionAbstractClass case), or even as a usual singleton (CompanionTraitFactory case). Guys, I more or less understand the difference between scala traits and abstract classes. I want to understand, why it was implemented this way and is there a chance that it will be supported in Scala in future.

1

1 Answers

2
votes

In the working case, you're calling a static forwarder added to your abstract class. You didn't used to get a static forward on your interface, but you do in 2.12.