Die Sache, über die Sie nachdenken müssen, ist, warum Sie Ihre Action
benötigen, um die execute
Methode zu haben, mit zu beginnen. Wahrscheinlich haben Sie so etwas wie dies an anderer Stelle im Code:
def executeAll(actions: Seq[Action], params: Parameters) =
actions.foreach { _.execute(params) }
Beachten Sie, dass Sie hier Ihre actions
Liste Aktionen verschiedenen Typen enthalten. Wenn einige davon außer dem Parameter vom Typ A
und einige vom Typ B
sein müssen, wird es nicht funktionieren, weil Ihr params
Parameter nicht beides sein kann.
Aus diesem Grund können Sie eine Methode nicht überschreiben, um einen anderen Parametertyp in einer Unterklasse zu übernehmen (eigentlich können Sie, aber der Typ muss eine Superklasse vom ursprünglichen Typ sein, keine Unterklasse. Sie sagen das Funktionen sind Contravariant in ihren Parametertypen für diese Reas, aber ich schweife ab).
Wenn Ihr Action1
und Action2
tatsächlich allgemein mit ihren Parametern umgehen, durch das Merkmal Schnittstelle, ohne dass sie einer bestimmten Art zu sein, dann ist die Lösung einfach: die Erklärungen Ihrer zwingenden Methoden override def execute(params: Parameters)
sein ändern.
Ist dies nicht der Fall ist, und Action1
kann nur mit Parametern vom Typ A
, dann (1) gibt es wahrscheinlich (obwohl nicht notwendigerweise) etwas falsch mit Ihrem dewsign beschäftigt, und (2) Sie müssen gehen mit Parametrisierungslösung, wie die andere Antwort suggeriert. Aber dann würden Sie haben alle ihre Plätze tauschen, die sich mit Action
auch:
def executeAll[T <: Parameters](actions: Seq[Action[T]], params: T) = ...
Diese Erklärung Einschränkungen der Typ des params
Argument entsprechen, was die Aktionen in der Liste erwarten, so dass Action1.execute
nicht sein versehentlich mit B
aufgerufen.
Nun, wie Sie im Kommentar zu der anderen Antwort erwähnt haben, können Sie keine Aktionen unterschiedlicher Art mischen, weil es keinen Sinn ergibt: Sie sind im Wesentlichen verschiedene Klassen. Wenn Sie nicht die execute
Methode verwenden wollen, und wollen einfach nur die Liste der verschiedenen Aktionen des Codes um einige Stück zu übergeben, können Sie das Wildcard-Syntax verwenden:
val actions: List[Action[_] = List(Action1(...), Action2(...))
Wieder einmal diese Liste als dienen kann generischer Container für Aktionen eines beliebigen Typs, aber Sie können ihn nicht verwenden, um die Methode execute
generisch anzuwenden, da dies zur Folge hätte, dass der Parameter verschiedene Typen gleichzeitig hat.
Ich musste auch List [Actions] übergeben, wenn ich das Merkmal parametrieren, erlaubt es mir nicht, zu tun "val actionList: Liste [Aktion] = Liste (action1, action2)". Vielleicht fehlt mir etwas in Scala (noch neu dazu :)) – chinmayv