“MyType” problem: Do I have to use abstract types (or generics) in Scala to return the actual class?

前端 未结 3 848
南旧
南旧 2020-12-08 17:41

I am not sure if there is a better way of doing this:

trait Animal {
  val name: String
  val weight: Int

  type SubAnimal <: Animal

  def updateName(n:         


        
相关标签:
3条回答
  • 2020-12-08 18:02

    This should work:

    trait Animal[T] {
      self:T =>
    
      val name: String
      val weight: Int
    
      def updateName(n: String): T = returnMe(n, this.weight)
      def updateWeight(w: Int): T = returnMe(this.name, w)
      // Abstract protected method
      protected def returnMe(n: String, w: Int): T
    }
    
    case class Dog(name: String, weight: Int) extends Animal[Dog] {
      override def returnMe(n: String, w: Int): Dog = Dog("Dog: " + name, w)
    }
    
    case class Cat(name: String, weight: Int) extends Animal[Cat] {
       override def returnMe(n: String, w: Int): Cat = Cat("Cat: " + name, w)
    }
    

    Something like case class Cat(name: String, weight: Int) extends Animal[Dog] gets rejected by the compiler. Code stolen adapted from http://oldfashionedsoftware.com/2009/12/10/self-help/

    0 讨论(0)
  • 2020-12-08 18:06

    Using type parametrization?

    trait Animal[A <: Animal[A]] {
      val name: String
      val weight: Int
    
      def updateName(n: String) = returnMe(n, this.weight)
      def updateWeight(w: Int) = returnMe(this.name, w)
      // Abstract protected method
      protected def returnMe(n: String, w: Int): A
    }
    
    case class Dog(name: String, weight: Int) extends Animal[Dog] {
      override def returnMe(n: String, w: Int) = Dog("Dog: " + name, w)
    }
    
    case class Cat(name: String, weight: Int) extends Animal[Cat] {
      override def returnMe(n: String, w: Int) = Cat("Cat: " + name, w)
    }
    
    0 讨论(0)
  • 2020-12-08 18:11

    Some recent discussion on this topic... What you're looking for is commonly referred to as "MyType", and the typical Scala/Java encoding for it uses recursive type parameters:

    public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { 
        public final int compareTo(E o) 
        // ... 
    }
    
    0 讨论(0)
提交回复
热议问题