Java générique de la méthode de l'héritage et de remplacer les règles
J'ai une classe abstraite qui a une méthode générique et je veux remplacer le générique de la méthode par substitution des types spécifiques pour le paramètre générique. Donc, en pseudo-code que j'ai est la suivante:
public abstract class GetAndParse {
public SomeClass var;
public abstract <T extends AnotherClass> void getAndParse(T... args);
}
public class Implementor extends GetAndParse {
//some field declarations
//some method declarations
@Override
public <SpecificClass> void getAndParse(SpecificClass... args) {
//method body making use of args
}
}
Mais pour une raison que je ne suis pas autorisé à le faire? Ai-je fait une sorte d'erreur de syntaxe ou est ce genre d'héritage et impérieuses pas permis? Clairement, j'obtiens une erreur à propos de @Override
parce que l'IDE eclipse rappelle sans cesse à moi pour mettre en œuvre getAndParse
.
Voici comment je veux le code ci-dessus fonctionne. Quelque part dans mon code il y a une méthode qui s'attend à des instances d'objets qui implémentent GetAndParse
qui signifie qu'ils ont un getAndParse
méthode que je peux utiliser. Quand je l'appelle getAndParse
sur cet exemple, le compilateur vérifie pour voir si j'ai utilisé des instances spécifiques de T
de la bonne façon, donc en particulier T
devrait s'étendre AnotherClass
et il devrait être SpecificClass
.
- le pseudo-code est trop abstrait, besoin de plus d'info
- À l'aide de
public abstract <T extends AnotherClass> void getAndParse(Args... args);
n'a pas de sens. Quel est le type de paramètre bon? Comment le compilateur de déterminer sa valeur réelle et où faut-il l'utiliser? - Pourriez-vous nous faire un exemple complet, qui est en fait compilable (en dehors de la problématique de l'erreur) et produit l'erreur que vous avez mentionné?
- Vous avez raison, j'ai changé les méthodes pour rendre l'utilisation spécifique du type générique.
Vous devez vous connecter pour publier un commentaire.
Ce que nous avons ici est de deux méthodes différentes avec chaque type de paramètres, chaque.
C'est une méthode avec un paramètre de type nommé T, et délimitée par
AnotherClass
, ce qui signifie que chaque sous-type deAnotherClass
est autorisé en tant que paramètre de type.C'est une méthode avec un paramètre de type nommé
SpecificClass
, délimitée parObject
(ce qui signifie que chaque type est accueilli comme un paramètre de type). Voulez-vous vraiment cela?Est le type de paramètre est utilisé à l'intérieur
Args
? Je pense que le problème serait là.Le sens de
est que le appelant de la méthode peut décider avec quel type de paramètre qu'il veut appeler la méthode, tant que c'est une sous-type de
AnotherClass
. Cela signifie que, en effet, la méthode peut être appelée avec des objets de typeAnotherClass
.Depuis l'appelant peut décider le type de paramètre, vous ne pouvez pas dans une sous-classe d'affiner le type de paramètre à
SpecificClass
- ce ne serait pas une implémentation de la méthode, mais une autre méthode du même nom (la surcharge).Peut-être vous voulez quelque chose comme ceci:
Maintenant la
getAndParse
méthode implémente le parent méthode de la classe.SpecificClass
est une extension deAnotherClass
.Vous voyez ce problème à cause du concept appelé "Effacement" en Java Génériques.
Java utilise "effacement" pour une compatibilité descendante. j'.e code Java qui n'a pas utiliser des génériques.
Processus D'Effacement:
Le compilateur va d'abord faire une vérification de type, puis il va supprimer(effacer) tous les paramètres de type, autant que possible, et également d'insérer TypeCasting où c'est nécessaire.
exemple:
deviendra
Dans la classe "Implementor.java",
Le code
deviendra
le compilateur va voir que vous n'avez pas mis en œuvre la méthode abstraite correctement.
Il y a une incompatibilité entre la méthode abstraite et la mise en œuvre de la méthode. C'est pourquoi vous voyez l'erreur.
Plus de détails peuvent être trouvés ici.
http://today.java.net/pub/a/today/2003/12/02/explorations.html
Non, il n'est pas valide. Qu'arriverait-il si quelqu'un avec un
GetAndParse
de référence appelé avec un autre classe étendantAnotherClass
?GetAndParse
et fixe le type deT
àSpecficClass
qui le compilateur vérifie s'étendAnotherClass
ensuite dans mon code, quand j'ai un exemple deImplementor
et appelgetAndParse
avec un type qui ne correspond pas àSpecificClass
je devrais recevoir un message d'erreur.GetAndParse foo = new Implementor();
vous devez pouvoir appelerfoo.getAndParse
pour toute extension de AnotherClass - Si le compilateur n'a pas respecter cela, vous pourriez tout aussi bien utiliser l'Objet, le point de génériques est de s'assurer au moment de la compilation de sécurité de typeQui devient un non-sens quand quelqu'un a une référence de type GetAndParse et tente d'appeler le getAndParse méthode. Si le Chat et le Chien étendre AnotherClass. Je devrais attendre d'être en mesure d'appeler GetAndParse#getAndParse avec soit un Chat ou un Chien. Mais la mise en œuvre a tenté de limiter et de le rendre moins compatible!
Vous ne pouvez pas remplacer de type T, car il ya en fait (au niveau du compilateur; si vous le souhaitez) une seule méthode
getAndParse
en raison du type d'effacement (voir autre réponse):Pour chaque type de T, la même méthode est utilisée.
Vous pouvez surcharge (je pense):
mais ce ne sera pas une méthode différente de (1) ant il pas être appelé par le code générique:
Méthode statique ne peut pas remplacer
Méthode privée ne peut pas remplacer
Dernière méthode ne pouvez pas remplacer