Search code examples
scalainheritancecomposition

Dynamic inheritance in Scala


I have an abstract grandparent class named Grandparent, and a parent class named ParentOne, and several children classes named ChildOne, ChildTwo, ChildThree, ... and so on.

They are written as following:

abstract class Grandparent {
    val value: Int
    def print(): Unit = println(value)
}

class ParentOne extends Grandparent {
    override val value: Int = 1
}

class ChildOne extends ParentOne
class ChildTwo extends ParentOne
class ChildThree extends ParentOne

What I am aiming for is to provide a method for changing the value printed in all Child classes to, for example, 2. I want the method to be as simple as it can.

The result will be something like creating a class ParentTwo as following and making all Child classes inherit it instead of ParentOne.

class ParentTwo extends Grandparent {
    override val value: Int = 2
}

But I know this is impossible, since we can't dynamically change the superclass. I want to make the structure of the library to be better, to achieve the task above. What would be the simplest way to make it?


Solution

  • You wrote

    What I am aiming for is to provide a method for changing the

    Which I'll take as a method which should mutate the value for all the children classes, right?

    If so, you could use the companion object of the Parent class to store a variable which could be changed at will:

    abstract class Grandparent {
        def value: Int
        def print(): Unit = println(value)
    }
    
    object Parent {
        var mutableValue: Int = 1
    }
    
    class Parent extends Grandparent {
        override def value: Int = Parent.mutableValue
    }
    
    class ChildOne extends Parent
    class ChildTwo extends Parent
    class ChildThree extends Parent
    

    Example of use:

    pablo-pablo@ val c = new ChildOne() 
    c: ChildOne = ammonite.$sess.cmd6$ChildOne@4ad10ef2
    pablo-pablo@ c.value 
    res12: Int = 12
    pablo-pablo@ Parent.mutableValue = 30 
    
    pablo-pablo@ c.value 
    res14: Int = 30