简体   繁体   中英

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. 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.

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. This is a highly simplified version to express my problem, so the implementation of create has been cut down. (The actual create method needs to access the object's fields, sending them to a database, etc..)

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

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 . Try making it a def that gets overridden by the concrete class:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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