2017-07-21 17 views
1

Ich versuche allgemeine apply Methode zu schreiben, um als Factory-Methode für untergeordnete Klassen zu dienen. Was ich kam mit folgt:Begleitobjekt für Merkmal in Scala

trait A 

object A { 
    def apply[T <: A](someParam: String): T { 
     new T() 
    } 
} 

class B private extends A 
class C private extends A 

So kann man neue B oder C-Instanz erstellen:

def main(args: Array[String]): Unit = { 
    A[B]("test") 
} 

Ist es akzeptabel, dass Merkmal ein begleitendes Objekt Gibt es einen besseren Weg, dies zu implementieren ?

+1

Soweit Begleiter-Objekt für ein Merkmal geht, ist es in Ordnung. Was deine andere Frage betrifft ... Hast du versucht, deinen Code zu kompilieren? – Dima

+0

Sie wollen wahrscheinlich 'Siegel Merkmal A' und http://engineering.monsanto.com/2016/01/11/algebraic-data-types/ – Reactormonk

+0

@Reactormonk' C' und 'B' sind nicht in der gleichen Datei, also bin ich Ich bin mir nicht sicher über "versiegelte Eigenschaft", aber ich werde diesen Link überprüfen. – gorros

Antwort

3

Sie könnte:

trait A 

    object A { 
    def apply[T <: A ](someParam: String) (implicit ev: ClassTag[T]): T ={ 
     ev.runtimeClass.newInstance().asInstanceOf[T] 
    } 
    } 

Aber es ist nicht sehr nützlich, mit unterschiedlichem Konstruktor für jede Unterklasse

sealed trait A 

    object A { 
    def apply[T <: A](someParam: String)(implicit ev: T): T = { 
     ev 
    } 
    } 

    class B(n: Int) extends A  
    class C(n: String) extends A 

    object B { 
    implicit def defaultCons: B = new B(1) 
    } 

    object C { 
    implicit def defaultCons: C = new C("hi") 
    } 

Oder Sie könnten auch über Kombination von ClassTag Ansatz mit Mustererkennung basierend auf der Klasse gehen anstatt Reflektion zur Instanziierung zu verwenden.

+0

Danke @Jatin. Es sieht so aus, wonach ich gesucht habe. Ich werde diesen Ansatz versuchen und die Antwort markieren, wenn sie meinen Bedürfnissen entspricht. Ich kenne "ClassTag" nicht, aber ich habe es schon einige Male gesehen. Können Sie einen Link zu einer Ressource mit weiteren Details bereitstellen? – gorros

+0

Sie antworten funktioniert, aber wahrscheinlich werde ich versuchen, einen anderen Weg zu gehen. Vielen Dank. – gorros

Verwandte Themen