简体   繁体   中英

Scala Subclass change return type without override

Let's say I have a class called A :

class A(i: Int) {
  //private def to initialize a calculated value
  def maintainedValue : Int = calculatedValue

  def double : A = new A(maintainedValue * 2)
  def combine(other: A) : A = new A(maintainedValue + other.maintainedValue)
  def addAmt(amt : Int) : A = new A(maintainedValue  + amt)
  // Many many more methods
}

I want to define a class B that extends class A such that it's methods, almost all of which have similar logic, return an object of class B :

class B(i: Int) extends A(i) {
  //private def to initialize a differently calculated value
  def maintainedValue : Int = diffCalculatedValue

  //Change all other methods to return type B without override???
}

Is it possible to do this without overriding all the methods?

Is there a simple way to instantiate these new instances with a variable/dynamic class?

Perhaps there is a more elegant way to do this?

How about having base trait with common logic and two implementation?

object App extends App {
  println(A(1).double)
  println(B(1).double)
}


trait A {
  type TYPE

  def create(i: Int): TYPE

  def maintainedValue: Int

  def double: TYPE = create(maintainedValue * 2)

  def addAmt(amt: Int): TYPE = create(maintainedValue + amt)
}

trait B extends A {
}

object A {

  def apply(i: Int) = new AImpl(i)

  case class AImpl(i: Int) extends A {
    override type TYPE = A

    override def create(i: Int) = A(i)

    override def maintainedValue: Int = 2
  }

}

object B {

  def apply(i: Int): B = new BImpl(i)

  case class BImpl(i: Int) extends B {

    override type TYPE = B

    override def create(i: Int): TYPE = B(i)

    override def maintainedValue: Int = 1
  }

}

One solution, and the simplest one in my opinion, is to change class A to have a structure such that a single method handles object creation:

def create(i: Int): TYPE = new B(i)

And just use an implicit method in class B to handle casting when calling the unaltered methods:

private implicit def convert(a: A): B = new B(a.maintainedValue)

Short and sweet, though I'm curious how efficient and/or scale-able this solution is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM