简体   繁体   English

Scala抽象类/特征,其方法返回子类型

[英]Scala abstract class/trait with methods that return the sub-type

Lately I've found myself working with different objects with similar structures (using play framework, but that's not really important) that I would like to store as different classes. 最近,我发现自己要使用结构相似的不同对象(使用播放框架,但这并不是很重要),我想将它们存储为不同的类。 They'll often have CRUD methods that are fundamentally the same, so I would like each of these classes to inherit from an abstract type to cut down on code duplication. 他们通常会使用从根本上相同的CRUD方法,因此我希望这些类中的每一个都可以从抽象类型继承来减少代码重复。 The problems I'm running into are: 1.) Being able to return the sub-type, and 2.) Accessing fields of the sub-type within these abstract methods. 我遇到的问题是:1.)能够返回子类型,并且2.)在这些抽象方法中访问子类型的字段。

I was successfully able to get this working (in a more fleshed-out version) with get methods taking advantage of apply , but now I've hit a wall. 我可以通过利用apply get方法成功实现此工作(更加充实的版本),但是现在我遇到了麻烦。 This is a highly simplified version to express my problem, so the implementation of create has been cut down. 这是一个高度简化的版本,用于表达我的问题,因此create的实现已被减少。 (The actual create method needs to access the object's fields, sending them to a database, etc..) (实际的create方法需要访问对象的字段,将其发送到数据库等。)

abstract class FileSystemObject(id: Int, path: String)

trait FileSystem[T <: FileSystemObject] {
    val table: String

    def apply(id: Int, path: String): T

    def create(obj: T): Option[T] = Some(apply(1, obj.path))

}

case class File(id: Int, path: String) extends FileSystemObject(id, path)

object File extends FileSystem[File] {
    val table: String = "files"
}

.. Which results in error: value path is not a member of type parameter T ..这将导致error: value path is not a member of type parameter T

At this point, it seems the solution I've chosen is horribly flawed, but I don't know how to proceed from here. 在这一点上,我选择的解决方案似乎存在严重缺陷,但是我不知道如何从这里继续。

You need path to be accessible on FileSystemObject in order for it to be seen on T . 您需要在FileSystemObject上可访问的path ,以便使其在T上可见。 Try making it a def that gets overridden by the concrete class: 尝试将其定义为具体类覆盖的def

abstract class FileSystemObject {
  def id: Int
  def path: String
}

case class File(id: Int, path: String) extends FileSystemObject

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

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