Les méthodes remplacées peuvent-elles avoir différents types de retour ?
java
methods
overriding
santidoo
la source
la source
error: method() in subclass cannot override method() in superclass
Réponses:
Java prend en charge les types de retour * covariants pour les méthodes remplacées. Cela signifie qu'une méthode remplacée peut avoir un plus type de retour spécifique. Autrement dit, tant que le nouveau type de retour est attribuable au type de retour de la méthode que vous remplacez, il est autorisé.
Par exemple:
Ceci est spécifié dans la section 8.4.5 de la spécification du langage Java :
("| R2 |" fait référence à l'effacement de R2, tel que défini au §4.6 du JLS .)
* Avant Java 5, Java avait des types de retour invariants , ce qui signifiait le type de retour d'un remplacement de méthode nécessaire pour correspondre exactement à la méthode remplacée.
la source
Oui, cela peut différer, mais il y a certaines limites.
Avant Java 5.0, lorsque vous remplacez une méthode, les paramètres et le type de retour doivent correspondre exactement. Dans Java 5.0, il introduit une nouvelle fonctionnalité appelée type de retour covariant. Vous pouvez remplacer une méthode avec la même signature mais renvoie une sous-classe de l'objet renvoyé. En d'autres termes, une méthode dans une sous-classe peut retourner un objet dont le type est une sous-classe du type retourné par la méthode avec la même signature dans la superclasse.
la source
Oui, s'ils renvoient un sous-type. Voici un exemple:
Ce code se compile et s'exécute.
la source
En gros, le type de retour oui de la méthode de remplacement peut être différent. Mais ce n'est pas simple car il y a des cas impliqués dans cela.
Cas 1: si le type de retour est un type de données primitif ou void.
Sortie: Si le type de retour est vide ou primitif, le type de données de la méthode de classe parent et de la méthode de remplacement doit être le même. Par exemple, si le type de retour est int, float, string alors il devrait être le même
Cas 2: Si le type de retour est un type de données dérivé:
Sortie: Si le type de retour de la méthode de classe parent est un type dérivé, le type de retour de la méthode de substitution est le même type de données dérivé de la sous-classe que le type de données dérivé. Par exemple, supposons que j'ai une classe A, B est une sous-classe de A, C est une sous-classe de B et D est une sous-classe de C; alors si la super classe retourne le type A, alors la méthode de substitution est la sous-classe peut retourner le type A, B, C ou D, c'est-à-dire ses sous-types. Ceci est également appelé covariance.
la source
oui C'est possible .. renvoie le type peut être différent uniquement si le type de retour de la méthode de classe parent est
un super type de type de retour de la méthode de classe enfant ..
signifie
Si tel est le type de retour, un autre type de retour peut être autorisé ...
la source
Eh bien, la réponse est oui et non.
dépend de la question. tout le monde ici a répondu à propos de Java> = 5, et certains ont mentionné que Java <5 ne comporte pas de types de retour covariants.
en fait, la spécification du langage Java> = 5 le prend en charge, mais pas l'environnement d'exécution Java. en particulier, la JVM n'a pas été mise à jour pour prendre en charge les types de retour covariants.
dans ce qui était alors considéré comme un mouvement "intelligent" mais qui a fini par être l'une des pires décisions de conception de l'histoire de Java, Java 5 a implémenté un tas de nouvelles fonctionnalités de langage sans modifier la JVM ou la spécification du fichier de classe. au lieu de cela, toutes les fonctionnalités ont été implémentées avec ruse en javac: le compilateur génère / utilise des classes simples pour les classes imbriquées / internes, l'effacement de type et le cast pour les génériques, les accesseurs synthétiques pour la classe nested / interne privée "amitié", les champs d'instance synthétiques pour les 'this' externes pointeurs, champs statiques synthétiques pour les littéraux '.class', etc., etc.
et les types de retour covariants sont encore plus de sucre syntaxique ajouté par javac.
par exemple, lors de la compilation de ceci:
javac affichera deux méthodes get dans la classe Derived:
la méthode de pont générée (marquée
synthetic
etbridge
en bytecode) est en fait ce qui se substitueObject:Base:get()
car, pour la JVM, les méthodes avec différents types de retour sont complètement indépendantes et ne peuvent pas se substituer les unes aux autres. pour fournir le comportement attendu, le pont appelle simplement votre méthode "réelle". dans l'exemple ci-dessus, javac annotera à la fois les méthodes bridge et real dans Derived with @SomeAnnotation.notez que vous ne pouvez pas coder manuellement cette solution en Java <5, car les méthodes bridge et real ne diffèrent que par le type de retour et ne peuvent donc pas coexister dans un programme Java. mais dans le monde JVM, les types de retour de méthode font partie de la signature de méthode (tout comme leurs arguments) et donc les deux méthodes nommées de la même manière et prenant les mêmes arguments sont néanmoins considérées comme complètement indépendantes par la JVM en raison de leurs types de retour différents, et peuvent coexister.
(BTW, les types de champs font également partie de la signature de champ en bytecode, il est donc légal d'avoir plusieurs champs de types différents mais nommés de la même manière dans une seule classe de bytecode.)
donc pour répondre pleinement à votre question: la JVM ne prend pas en charge les types de retour covariants, mais javac> = 5 le simule au moment de la compilation avec une couche de sucre syntaxique sucré.
la source
Remplacer et renvoyer les types et les renvois covariants
la sous-classe doit définir une méthode qui correspond exactement à la version héritée. Ou, à partir de Java 5, vous êtes autorisé à modifier le type de retour dans le
exemple de code
Java 5, ce code se compilera. Si vous tentez de compiler ce code avec un compilateur 1.4, vous direz que vous essayez d'utiliser un type de retour incompatible - sandeep1987 il y a 1 min
la source
Les autres réponses sont toutes correctes, mais étonnamment toutes laissant de côté l'aspect théorique ici: les types de retour peuvent être différents, mais ils ne peuvent restreindre le type utilisé dans la super classe qu'à cause du principe de substitution de Liskov .
C'est super simple: quand vous avez du code "client" qui appelle une méthode:
alors ce qui précède doit fonctionner (et renvoyer quelque chose qui est une
int
n'importe quelle implémentation debar()
est invoquée).Signification: s'il existe une sous-classe Bar qui remplace,
bar()
vous devez toujours renvoyer quelque chose qui ne rompt pas le "code de l'appelant".En d'autres termes: supposons que la base
bar()
est supposée retourner int. Ensuite, une sous-classe pourrait revenirshort
- mais paslong
parce que les appelants seront bien traités avec uneshort
valeur, mais pas unlong
!la source
Le type de retour doit être identique ou un sous-type du type de retour déclaré dans la méthode remplacée d'origine dans la superclasse.
la source
OUI c'est possible
la source
Oui. Il est possible que les méthodes remplacées aient un type de retour différent.
Mais les limitations sont que la méthode remplacée doit avoir un type de retour qui est un type plus spécifique du type de retour de la méthode réelle.
Toutes les réponses ont donné des exemples de la méthode surchargée pour avoir un type de retour qui est une sous-classe du type de retour de la méthode réelle.
Par exemple :
Mais cela n'est pas seulement limité aux sous-classes: même les classes qui implémentent une interface sont un type spécifique de l'interface et peuvent donc être un type de retour là où l'interface est attendue.
Par exemple :
la source
la source