Reputation: 3072
I noticed that Scala has case classes. These appear to be for pattern matching, but I like that I can do this with them:
val bankAccount1 = new BankAccount("Daniel", 100)
val bankAccount2 = bankAccount1.copy(funds = 200)
Now "Daniel" has two bank accounts, one with $100 and one with $200. But when things get more complicated, BankAccount
needs to be sub-classed and this doesn't work because case classes can't extend other case classes.
I want immutable classes than can be extended into more immutable classes. Like I want to be able to extend BankAccount
to have immutable sub-classes SavingsBankAccount
and CheckingBankAccount
. I'm not sure if at this point I need to extend/implement the Clonable
interface or define custom copy methods or something like that. I don't want to have to put too much boilerplate in the classes.
(If possible), how do I make immutable classes in Scala that can be copied and sub-classed and that aren't overly messy or verbose?
Upvotes: 1
Views: 160
Reputation: 3699
Think if your BankAccount
really needs to be concrete.
Can I have a BankAccount that is not of the type Savings or Checking?
If the answer to this question is no (in this example I guess it is), you could use a abstract class or...
traits !
http://www.scala-lang.org/old/node/126
When you don't really need hierarchies, you can do a lot with traits. Actually traits are better than abstract classes since you can have composability.
I found out programming in scala that most of the time you don't need to extend concrete objects, specially classes that just pack data.
If you really need BankAccount
to be concrete, that I guess you are left with what you already suggested. :(
Upvotes: 0
Reputation: 2130
I think that the idiomatic way of doing that in Scala would be using encapsulation instead of inheritance. For instance you could have:
case class BankAccount(id: AccountId, customer: Customer)
case class SavingsBankAccount(account: BankAccount, line: SavingsLine)
This way you would keep the good properties of immutability and automatic apply, unapply, equals, hashCode and copy method generation.
However if you really wanted to use inheritance you have no other choice than to roll out your own custom solution. For instance implementing a trait SubclassableCaseClass
which implements helper methods for a quick definition of the methods case classes give you for free.
Upvotes: 3