如何在Scala中创建功能齐全的不可变类?

时间:2015-10-25 18:53:01

标签: java scala copy prototype

我注意到Scala有案例类。这些似乎是用于模式匹配,但我喜欢我可以用它们做到这一点:

val bankAccount1 = new BankAccount("Daniel", 100)
val bankAccount2 = bankAccount1.copy(funds = 200)

现在"丹尼尔"有两个银行账户,一个有100美元,一个有200美元。但是当事情变得更复杂时,BankAccount需要进行细分,这不起作用,因为案例类不能扩展其他案例类。

我想要不可变的类,而不是可扩展到更多不可变的类。就像我希望能够将BankAccount扩展为具有不可变子类SavingsBankAccountCheckingBankAccount。我不确定在这一点上我是否需要扩展/实现Clonable接口或定义自定义复制方法或类似的东西。我不想在课堂上放太多样板。

(如果可能的话),如何在Scala中创建可以复制和子类的不可变类,并且不会过于混乱或冗长?

2 个答案:

答案 0 :(得分:3)

我认为在Scala中这样做的惯用方法是使用封装而不是继承。例如,您可以:

case class BankAccount(id: AccountId, customer: Customer)
case class SavingsBankAccount(account: BankAccount, line: SavingsLine)

这样你就可以保持不变性和自动应用,unapply,equals,hashCode和copy方法生成的良好属性。

但是,如果您真的想要使用继承,除了推出自己的自定义解决方案之外别无选择。例如,实现一个trait SubclassableCaseClass,它实现了帮助方法,可以快速定义方法的案例类,免费提供。

答案 1 :(得分:0)

想想你的BankAccount是否真的需要具体。

我可以拥有不属于Savings或Checking?类型的BankAccount吗?

如果这个问题的答案是否定的(在本例中我猜它是),你可以使用抽象类或...

特质

http://www.scala-lang.org/old/node/126

当你真的不需要等级时,你可以用特征做很多事情。实际上,traits比抽象类更好,因为你可以具有可组合性。

我在scala中发现编程,大部分时间你不需要扩展具体对象,特别是只包装数据的类。

如果你真的需要BankAccount具体,我猜你会留下你已经提出的建议。 :(