Scala attribute function: returns an instance of a derived type

I have a book with traits that looks like

trait Book{
 val sqlTableName;
 def getAll: Seq[ Book ] = { magicSQLFn( $"SELECT * FROM $sqlTableName" ) }
}

I have two derived types:

class Fiction extends Book{ val sqlTableName = "fiction" }
class NonFiction extends Book{ val sqlTableName = "nonfiction" );

I need to get Seq[Fiction]when I call getAllinto an instance Fiction, say fiction1. I know that one way to do is to do .map( _.asInstanceOf[ Fiction ] ). However, is there a way to avoid this?

In fact, I understand that a less correct way would be to define a companion object for Fictionwhich extends Bookso that I can call an getAllinstance on this object (as opposed to executing it as an instance), however in this case I'm not sure how I will convert individual elements in the returned sequence to instances of the class Fiction, because the class Fictionwill no longer be inferred from Book. Should I have two distinguishing features Book? One of them is the super of these objects, and the other is the superclass of these classes?

EDIT: @Travis Brown's answer solves my original problem. If anyone has comments on how to handle this using companion objects rather than class instances, this is also great!

+4
1

F- , :

trait Book[B <: Book[B]] {
  val sqlTableName;
  def getAll: Seq[B] = { magicSQLFn( $"SELECT * FROM $sqlTableName" ) }
}

class Fiction extends Book[Fiction] { val sqlTableName = "fiction" }
class NonFiction extends Book[NonFiction] { val sqlTableName = "nonfiction" )

(, magicSQLFn - , .)

F- , , , Scala Java.

+7

All Articles