I stumble upon something that I hope is a bit of a basic problem. This is probably because I'm new to Scala, and I probably still miss some important concepts.
I am trying to program in FP mode, and data classes that do not have to have a mutable state are immutable, with some conversion methods for creating new objects to update them if necessary. However, I am afraid when it comes to preserving the return types of this method, when I have traits and common inheritance. I want to avoid messy tricks or similar things as little as possible, because for me it's still a learning experience.
See this example here, where I have an immutable class extending some features. The update method is intended to change data, call some method of the actual class (which is abstract in the attribute) and returns a new instance of the same class, updated to new data. You can match this with a pattern template.
trait MyTrait { val someDataVal : Integer; def update(newDataVal) : MyTrait = { //some logic takes place here, which is common abstractUpdate(newDataVal) } //some logic takes place, specific to the implementation class def abstractUpdate(newDataVal : Integer) : MyTrait } class MyClass(dataVal : Integer) extends MyTrait { override val someDataVal = dataVal def abstractUpdate(newDataVal : Integer) : MyClass = { //some class specific logic here ........ MyClass(newDataVal) } def someOtherFunction() : Integer = { //some logic here ..... } }
I obviously don't want to copy and paste update() into MyClass I want it to stay in the dash, so that I can use it with any class extending it. However, if I try to call it, I get an object of type MyTrait , and therefore I cannot call it someOtherFunction() .
What is the right Scala approach to achieve such reuse of OO and still keep my code clean?
UPDATE
Pay attention to the places where I put //some logic takes place here , this means that I may have some code that I want to centralize in the attribute, and not copy and paste into each specific class that extends it. It is just a skeleton to illustrate the problem. Thank you for your time.
UPDATE
Sample code based on a response provided by wheat. The problem is with return this .
trait MyTrait[T <: MyTrait[T]]{ def update(newValue: Int): T = { if (newValue == 0) return this;