繁体   English   中英

Scala扩展参数化抽象类

[英]Scala Extending Parameterized Abstract Class

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

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引起的,这些val只能由构造函数初始化。 有没有更好的方法来创建这里详述的关系,或者我是否必须因为想要仅使用不可变对象而受到影响?

首先,case-class构造函数中的val修饰符是多余的,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

此外,如果您将sealed添加到trait Post ,您可以安全地使用Post的子类型进行模式匹配,而不会意外丢失案例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM