explicite de la coulée de super-classe de la sous-classe
public class Animal {
public void eat() {}
}
public class Dog extends Animal {
public void eat() {}
public void main(String[] args) {
Animal animal = new Animal();
Dog dog = (Dog) animal;
}
}
La cession Dog dog = (Dog) animal;
ne génère pas d'erreur de compilation, mais à l'exécution, il génère un ClassCastException
. Pourquoi ne peut pas le compilateur de détecter cette erreur?
- VOUS dites que le compilateur détecte PAS l'erreur.
Vous devez vous connecter pour publier un commentaire.
À l'aide d'un cast vous êtes essentiellement de dire au compilateur "faites-moi confiance. Je suis un professionnel, je sais ce que je fais et je sais que même si tu ne peux pas le garantir, je vous dis que cette
animal
variable va certainement être un chien."Puisque l'animal n'est pas un chien (c'est un animal, vous pourriez faire
Animal animal = new Dog();
et c'est un chien) la VM déclenche une exception à l'exécution parce que vous avez violé la confiance (vous avez dit au compilateur que tout serait ok et il n'est pas!)Le compilateur est un peu plus intelligent que de simplement accepter aveuglément tout, si vous essayez et de la fonte d'objets dans les différentes hiérarchies d'héritage (fonte d'un Chien à une Chaîne de caractères par exemple), alors le compilateur va le jeter de retour à vous, car il sait que ne pourrait jamais travailler.
Parce que vous êtes essentiellement juste arrêter le compilateur de se plaindre à chaque fois que vous lancez, il est important de vérifier que vous n'aurez pas de provoquer un
ClassCastException
en utilisantinstanceof
dans une instruction if (ou quelque chose à cet effet.)Dog
t s'étendent deAnimal
!Parce que théoriquement
Animal animal
peut être un chien:Généralement, de passer n'est pas une bonne idée. Vous devriez éviter. Si vous l'utilisez, vous feriez mieux d'inclure un chèque:
Afin d'éviter ce genre de ClassCastException, si vous avez:
Vous pouvez définir un constructeur de B, qui prend un objet de A. de Cette façon, nous pouvons faire de la "fonte" par exemple:
Dog d = (Dog)Animal; //Compiles but fails at runtime
Ici que vous venez de dire au compilateur "faites-moi Confiance. Je sais
d
est vraiment se référant à uneDog
objet" bien qu'il ne l'est pas.Souviens compilateur est forcé à nous faire confiance quand nous faisons un triste.
Ainsi, lorsque la JVM lors de l'exécution chiffres que l'
Dog d
est en réalité référence à unAnimal
et pas unDog
objet qu'il dit.Hey... vous avez menti au compilateur et jette un gros
ClassCastException
.Donc, si vous êtes de passer vous devez utiliser
instanceof
test pour éviter de vissage.if (animal instanceof Dog) {
Dog dog = (Dog) animal;
}
Maintenant, une question vient à notre esprit. Pourquoi l'enfer est un compilateur permettant à l'abattus quand finalement, il va jeter un
java.lang.ClassCastException
?La réponse est que tout le compilateur peut faire est de vérifier que les deux types sont dans la même arborescence d'héritage, de sorte que selon le code que pourrait avoir
viennent avant les humbles, il est possible que
animal
est de typedog
.Considérons le code suivant snipet:
Toutefois, si le compilateur est sûr que le casting ne serait pas possible de travail, la compilation échoue. I. E. Si vous essayez de lancer des objets dans les différentes hiérarchies d'héritage
String s = (String)d; //ERROR : cannot cast for Dog to String
Dog d = new Dog();
Animal animal1 = d; //Works fine with no explicit cast
Animal animal2 = (Animal) d; //Works fine with n explicit cast
À la fois au-dessus de la sortie fonctionnera très bien sans aucune exception, car un Chien EST UN Animal, anithing d'un Animal peut faire, un chien peut le faire. Mais ce n'est pas vrai vica versa.
Le code génère une erreur de compilation car votre type d'instance est un Animal:
De passer n'est pas autorisé en Java pour plusieurs raisons.
Voir ici pour plus de détails.
Comme l'a expliqué, il n'est pas possible.
Si vous souhaitez utiliser une méthode de la classe fille, pour évaluer la possibilité d'ajouter la méthode de la super-classe (peut être vide) et l'appel de la sous-classes d'obtenir le comportement que vous voulez (sous-classe) grâce au polymorphisme.
Ainsi, lorsque vous appelez d.méthode() l'appel va réussir withoug casting, mais dans le cas où l'objet sera pas un chien, il ne sera pas un problème
De développer la réponse de @Caumons:
Maintenant, jetez un oeil à cette solution.
Maintenant nous tester l'application:
Et voici le résultat :
Maintenant, vous pouvez facilement ajouter de nouveaux champs à père de classe sans être inquiet de vos enfants des codes à briser;