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.