1
votes

I know I can add a companion object to a class for static def/val but my problem is I want it to comfirm to a trait. I want access to this static val or def as an abstract type (using the word static here in terms of the behaviour expected from java static) Consider this code

trait A {
  def aBehavior(): Unit
}
trait B {
  def bBehavior(): Unit
  def description: String
}

case class M extends A with B {
  override def aBehavior() = print("A behavior of M")
  override def bBehavior() = print("B behavior of M")
  override def description = "I'm M"
}

I want to be able to call M.description as a static method without having an instance of M. My use case is I have a spark dataset of M objects and I want to see the description property of M without getting a record from the dataset because that will result in a spark action / job Is there a scala pattern I can use for this. Thanks

2
Just to clarify, what's keeping you from just defining object M { def description = "I'm M" }? I'm not sure what you mean by "confirm to a trait" in the context of static methods - you cannot "implement" or "override" static members on the JVM.László van den Hoek
Looks like you have to do a bit of reading regarding singleton object docs.scala-lang.org/tour/singleton-objects.html Hope that helpsPavel
@LászlóvandenHoek Thanks for your comment. I need to use this as generic type B and not as type M. I have some generic code for all implementations of type B. If I could use it as M.description, I could write it in companion object as you suggested but I need to use this as B.descriptioninglorious_engineer
So creating an object B would do the trick then?László van den Hoek
So, if I understand correctly, for all types M, N, O and P you want a static call to B.description and expected different results for each call, depending on ... huh? Well, I think, you gonna have to have some type information of what you want described!Sascha Kolberg

2 Answers

2
votes

Just create a companion object for M which defines the static value and then reference that in the case class

object M {
  val description = "I'm M"
}
case class M extends A with B {
  override def description = M.description
}

or assuming commonality between subtypes

trait Description {
  val title: String
  val description = s"I'm ${title}"
}
object M extends Description {
  val title = "M"
}
object N extends Description {
  val title = "N"
}
case class M() extends A with B {
  override def description = M.description
}
case class N() extends A with B {
  override def description = N.description
}
1
votes

You can refactor description of B into another trait like:

trait BInfo {
  def description: String
}
trait B extends BInfo {
  def bBehavior(): Unit
  def bInfo: BInfo
  final override def description = bInfo.description
}
case class M() extends A with B {
  override def aBehavior() = print("A behavior of M")
  override def bBehavior() = print("B behavior of M")
  override def bInfo = M
}
object M extends BInfo {
  override def description = "I'm M"
}

val m = M()
M.description // I'm M
m.description // I'm M