oop - Scala扩展参数化抽象类

标签 oop scala inheritance

我对 Scala 相当陌生,正在编写一个 API 库并尝试仅使用 val 和不可变对象(immutable对象)(如果可能)。我正在尝试确定建模对象的正确方法。假设有几个“Post”对象,它们都共享一些公共(public)字段,并且每个都添加自己的特定字段:

abstract class Post(val id: Int, val name: String, ...)
case class TextPost(val id: Int, val name: String, ..., val text: String) extends Post(id, name, ...)
case class PhotoPost(val id: Int, val name: String, ..., val url: String) extends Post(id, name, ...)

这种方法增加了很多重复的声明和样板代码,尤其是在处理许多 Post 子类和在抽象类中声明的共享字段时。在我看来,这是由于使用只能由构造函数初始化的 vals 引起的。是否有更好的方法来创建此处详述的关系,或者我是否必须因为只想使用不可变对象(immutable对象)而遭受这种痛苦?

最佳答案

首先,val case-class 构造函数中的修饰符是多余的,Scala 编译器已经“免费”将它们提供给您(这是 case-classes 的特性之一)。如果您实际上尝试编译它,您将看到由于未声明的覆盖而发生错误:

abstract class Post(val id: Int, val name: String )
case class TextPost(id: Int, name: String) extends Post(id, name )
case class PhotoPost(id: Int, name: String) extends Post(id, name )

<console>:10: error: overriding value id in class Post of type Int;
 value id needs `override' modifier
           case class PhotoPost(id: Int, name: String) extends Post(id, name )
                                ^

我个人建议尽可能少地使用带有构造函数参数的抽象类。 Scala 的特性在这里做得更好。您(抽象地)声明字段,而不是构造函数参数;然后案例类开始了,由于他们自动提出他们的论点vals ,你就完成了:
trait Post { def id: Int; def name: String }
case class TextPost(id: Int, name: String, text: String) extends Post
case class PhotoPost(id: Int, name: String, url: String) extends Post

此外,如果您添加 sealedtrait Post ,您可以安全地使用 Post 的子类型在模式匹配中不会意外丢失案例。

关于oop - Scala扩展参数化抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12289806/

相关文章:

scala - 使用案例类显示表达式

scala - 除缩放外,是否还有其他Scala模板引擎?

oop - Fortran 2003/2008 子类的数据继承

java - 使用对象变量引用新的数据类型/对象

php - 在 Zend 中,为什么我们将 DB Model 类和 Mapper 类分开使用?

scala - Spark SQL : How to append new row to dataframe table (from another table)

java - 如何将多个接口(interface)分组为一个通用的单个接口(interface)?

c# - 使用存储库模式实现 Web 服务的正确方法是什么

php - 将 MySQL 连接查询与 OOP 和对象相关联的最佳实践方法

android - Android Activity 类中的面向对象范围和继承