scala générique de la redéfinition de méthode
J'ai une classe abstraite :
abstract class Foo(...){
def bar1(f : Foo) : Boolean
def bar2(f : Foo) : Foo
}
plusieurs classes d'étendre Foo et surcharger les méthodes
class FooImpl(...) extends Foo{
override def bar1(f : Foo) : Boolean {
...
}
override def bar2(f : Foo) : Foo {
...
}
}
Est-il possible, à l'aide de médicaments génériques (ou quelque chose) pour faire de la redéfinition des méthodes ont la parametertype de la sous-classe de la mettre en œuvre? Comme ceci :
class FooImpl(...) extends Foo{
override def bar1(f : FooImpl) : Boolean {
...
}
override def bar2(f : FooImpl) : FooImpl {
...
}
}
Je pensais à quelque chose le long de la ligne de la suite, mais cela ne semble pas fonctionner...
abstract class Foo(...){
def bar1[T <: Foo](f : T) : Boolean
def bar2[T <: Foo](f : T) : T
}
class FooImpl(...) extends Foo{
override def bar1[FooImpl](f : FooImpl) : Boolean {
...
}
override def bar2[FooImpl](f : FooImpl) : FooImpl{
...
}
}
Toute aide est très appréciée!
Merci.
OriginalL'auteur Jannik Luyten | 2011-01-07
Vous devez vous connecter pour publier un commentaire.
Dans cette version, les différentes sous-classes de
Foo
partageons tousFoo
comme une super-classe, mais de tenir la valeur de retour debar2
(ou les paramètres debar1
oubar2
) dans un contexte où tout ce que vous savez au sujet de votre objet (disons que c'est nomméeobj
), c'est que c'est unFoo
, vous devez utiliser le typeobj.T
que le type de la variable.Vous êtes correct.
OriginalL'auteur Ken Bloom
De faire Ken Blum deuxième version un peu plus agréable, vous pouvez utiliser l'auto types:
OriginalL'auteur Landei
T
doit être un type de paramètre sur laFoo
classe que vous héritez de, pas sur les méthodes elles-mêmes.Différentes sous-classes de
Foo
n'ont pas réellement d'un commun supertype dans cette version du code, car ils s'étendent à partir de différents paramétrages deFoo
. Vous pouvez utiliser paramétrée méthodes qui renvoient àFoo[T]
lorsque vous avez besoin de travailler avec le supertype, mais j'ai tendance à préférer le type abstrait solution que j'ai posté dans mon autre réponse, car il n'y a pas de fuite les détails de l'génériques pour toutes les autres fonctions qui ont à traiter avec des Foos.OriginalL'auteur Ken Bloom
Idéalement, vous combinez les choses mentionnées ci-dessus, c'est à dire
"[T <: Foo[T]]" signifie T est une sous-classe de Foo[T],
ET "l'auto:T =>" signifie que les Foo[T] est sous-classe de T, et, ensemble, c'est un peu bizarre façon de dire que Foo[T] est exactement le même que T.
Seul avec qui j'ai pu faire code suivant compile et fonctionne comme prévu:
OriginalL'auteur Baturinsky
Vous pouvez paramétrer
Foo
d'accomplir une partie de l'effet facilement:Si vous voulez exclure le second cas, il n'y a pas de façon simple de le faire avec les caractéristiques actuelles en Scala.
Aussi, une partie de ce que vous semblez vouloir ne fait pas de sens si vous donner une mise en œuvre effective dans
Foo
. SiFoo
promet de prendre touteFoo
mais vous donner une méthode qui insiste sur seulement unFood
, il va se casser si vous vous passez à une autre sous-classe deFoo
(par exempleFool
). Ainsi, le compilateur ne te laisserai pas faire ça.Fool
comme unFoo[Food]
moins c'est ce qu'il souhaite réellement.Je pense que nous pouvons faire confiance au programmeur de ne pas l'intention de définir
Fool
comme unFoo[Food]
, mais les erreurs se produisent. Si des erreurs n'a pas eu lieu, nous n'aurions probablement pas besoin de la vérification de type à tous 🙂OriginalL'auteur Rex Kerr