Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala: reuse subclass implementation as a subclass of two different classes?

To simplify my actual code let's say there are two classes, one a subclass of the other:

class Chair {
   val canFold = false;
   // ...
}

class FoldableChair extends Chair {
   val canFold = true;
   // ...
} 

and in my implementation I will have potentially hundreds of other subclasses of Chair or FoldableChair:

class Armchair extends ... {}
class DeckChair extends ... {} 
//... etc

For each of these subclasses, suppose each one has a lengthy implementation but I want to be able to have it sometimes extend Chair and sometimes extend FoldableChair - without duplicating the code. I'd like to do so without having the subclass itself be extended. Is this possible somehow? Do I need to use traits to do this?

I'd also like to be able to create particular instances of a subclass which sometimes extend Chair and sometimes extend FoldableChair, but that choice is made when instantiating it. Is this possible too? Thanks!

Edit: to clarify, what I really want is this:

class Armchair extends Chair {}

class ArmchairFoldable extends FoldableChair {}

but the implementation of Armchair and ArmchairFoldable are exactly the same. That is, I'd like to not duplicate their implementations.

like image 376
Heinrich Schmetterling Avatar asked Jan 27 '26 16:01

Heinrich Schmetterling


1 Answers

You can use an implementation trait; i.e., a trait that you mix in with a class and that provides additional members with their implementation.

Example:

class Chair {
   // you can use a def rather than a val as it's constant and
   // and doesn't need to occupy a field
   def canFold = false

   // ...
}

class FoldableChair extends Chair {
   override def canFold = true
   // ...
}

trait Extensible extends Chair {
    // this trait extends Chair to mean that it is only
    // applicable to Chair or subclasses of Chair
    def extend = /* ... */
}

class FoldableExtensibleChair extends FoldableChair with Extensible

Then you can write:

val a = new Chair // bare-bones chair

// decide at creation time that this one is extensible
val b = new Chair with Extensible

val c = new FoldableChair // non extensible

// use predefined class which already mixes in Extensible
val d = new FoldableExtensibleChair 
like image 190
Jean-Philippe Pellet Avatar answered Jan 30 '26 10:01

Jean-Philippe Pellet



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!