Quelle est la différence entre la coulée vers le haut et la coulée vers le bas en ce qui concerne la variable de classe
Quelle est la différence entre le haut-casting et vers le bas de la coulée à l'égard de variable de classe?
par exemple dans la classe de programme suivante Animal contient une seule méthode mais la classe de chien contient deux méthodes, puis comment nous jetons la variable de chien à la Variable D'Animal.
si le moulage est fait alors comment pouvons-nous appeler L'autre méthode du chien avec la variable de L'Animal.
class Animal
{
public void callme()
{
System.out.println("In callme of Animal");
}
}
class Dog extends Animal
{
public void callme()
{
System.out.println("In callme of Dog");
}
public void callme2()
{
System.out.println("In callme2 of Dog");
}
}
public class UseAnimlas
{
public static void main (String [] args)
{
Dog d = new Dog();
Animal a = (Animal)d;
d.callme();
a.callme();
((Dog) a).callme2();
}
}
9 réponses
Upcasting est un casting à un supertype, tandis que downcasting est un casting à un sous-type. La diffusion vers le haut est toujours autorisée, mais la diffusion vers le bas implique une vérification de type et peut lancer un ClassCastException
.
dans votre cas, un plâtre de Dog
à Animal
est un upcast, parce qu'un Dog
est-un Animal
. En général, vous pouvez upcast chaque fois qu'il ya un est-une relation entre deux classes.
Downcasting serait quelque chose comme ceci:
Animal animal = new Dog();
Dog castedDog = (Dog) animal;
fondamentalement, ce que vous faites est de dire au compilateur que vous savez ce que le type d'exécution de l'objet vraiment est. Le compilateur permettra la conversion, mais insérera quand même un contrôle de bon fonctionnement pour s'assurer que la conversion a du sens. Dans ce cas, la coulée est possible parce qu'à l'exécution animal
est en fait un Dog
même si le type statique de animal
est Animal
.
cependant, si vous deviez faire ceci:
Animal animal = new Animal();
Dog notADog = (Dog) animal;
vous auriez un ClassCastException
. La raison en est que le type d'exécution de animal
est Animal
, et donc quand vous dites à l'runtime d'effectuer le cast il voit que animal
n'est pas vraiment un Dog
et donc jette un ClassCastException
.
pour appeler la méthode d'une superclasse vous pouvez faire super.method()
ou en exécutant l'upcast.
pour appeler une sous-classe la méthode que vous avez à faire abattu. Comme indiqué ci-dessus, vous risquez normalement un ClassCastException
en faisant cela; cependant, vous pouvez utiliser l'opérateur instanceof
pour vérifier le type d'exécution de l'objet avant d'effectuer le moulage, ce qui vous permet d'empêcher ClassCastException
s:
Animal animal = getAnimal(); // Maybe a Dog? Maybe a Cat? Maybe an Animal?
if (animal instanceof Dog) {
// Guaranteed to succeed, barring classloader shenanigans
Dog castedDog = (Dog) animal;
}
la coulée vers le bas et la coulée vers le haut étaient les suivantes::
Upcasting : quand nous voulons lancer une sous-classe à la Super classe, nous employons Upcasting(ou l'élargissement). Cela se produit automatiquement, pas besoin de faire quoi que ce soit explicitement.
Downcasting : quand nous voulons lancer une classe Super à la sous-classe, nous utilisons Réduction (ou rétrécissement)), et la Downcasting N'est pas directement possible en Java, explicitement nous devons le faire.
Dog d = new Dog();
Animal a = (Animal) d; //Explicitly you have done upcasting. Actually no need, we can directly type cast like Animal a = d; compiler now treat Dog as Animal but still it is Dog even after upcasting
d.callme();
a.callme(); // It calls Dog's method even though we use Animal reference.
((Dog) a).callme2(); // Downcasting: Compiler does know Animal it is, In order to use Dog methods, we have to do typecast explicitly.
// Internally if it is not a Dog object it throws ClassCastException
Upcasting et downcasting sont des parties importantes de Java, qui nous permettent de construire des programmes compliqués en utilisant une syntaxe simple, et nous donne de grands avantages, comme le polymorphisme ou le groupement de différents objets. Java permet qu'un objet d'un type de sous-classe soit traité comme un objet de tout type de superclasse. Ceci est appelé upcasting. Upcasting est fait automatiquement, tandis que downcasting doit être fait manuellement par le programmeur , et je vais donner de mon mieux pour expliquer pourquoi est-ce si.
Upcasting et de passer ne sont PAS comme casting primitives de l'un à l'autre, et je crois que c'est ce qui provoque beaucoup de confusion, lorsque le programmeur commence à apprendre le casting des objets.
polymorphisme: toutes les méthodes en java sont virtuelles par défaut. Cela signifie que n'importe quelle méthode peut être dépassée lorsqu'elle est utilisée dans l'héritage, sauf si cette méthode est déclarée comme finale ou statique .
vous pouvez voir l'exemple ci-dessous comment getType();
fonctionne selon le type d'objet(chien,animal de compagnie,chien policier).
supposons que vous avez trois chiens
- chien-C'est la super classe.
- chien de compagnie - chien de compagnie étend chien.
-
chien policier - chien policier étend chien de compagnie.
public class Dog{ public String getType () { System.out.println("NormalDog"); return "NormalDog"; } } /** * Pet Dog has an extra method dogName() */ public class PetDog extends Dog{ public String getType () { System.out.println("PetDog"); return "PetDog"; } public String dogName () { System.out.println("I don't have Name !!"); return "NO Name"; } } /** * Police Dog has an extra method secretId() */ public class PoliceDog extends PetDog{ public String secretId() { System.out.println("ID"); return "ID"; } public String getType () { System.out.println("I am a Police Dog"); return "Police Dog"; } }
Polymorphisme: toutes les méthodes en java sont virtuelles par défaut. Cela signifie que n'importe quelle méthode peut être dépassée lorsqu'elle est utilisée dans l'héritage, à moins que cette méthode soit déclarée comme finale ou statique.(L'explication appartient au Concept des Tables virtuelles)
table virtuelle / table D'expédition: la table d'expédition d'un objet contiendra les adresses des méthodes liées dynamiquement de l'objet. Les appels de méthode sont effectués en récupérant l'adresse de la méthode à partir de la table de répartition de l'objet. La table de répartition est la même pour tous les objets appartenant à la même classe, et est donc typiquement partagée entre eux.
public static void main (String[] args) {
/**
* Creating the different objects with super class Reference
*/
Dog obj1 = new Dog();
` /**
* Object of Pet Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry about it
*
*/
Dog obj2 = new PetDog();
` /**
* Object of Police Dog is created with Dog Reference since
* Upcasting is done automatically for us we don't have to worry
* about it here even though we are extending PoliceDog with PetDog
* since PetDog is extending Dog Java automatically upcast for us
*/
Dog obj3 = new PoliceDog();
}
obj1.getType();
Imprime Normal Dog
obj2.getType();
Imprime Pet Dog
obj3.getType();
Imprime Police Dog
de Passer doivent être faites par le programmeur manuellement
quand vous essayez de invoquer la méthode secretID();
sur obj3
qui est PoliceDog object
mais référencé à Dog
qui est une classe super dans la hiérarchie qu'il jette erreur depuis obj3
n'ont pas accès à secretId()
méthode. pour invoquer cette méthode vous devez Downcast que obj3 manuellement à PoliceDog
( (PoliceDog)obj3).secretID();
qui imprime ID
de la même manière que invoquer la méthode dogName();
dans la classe PetDog
vous devez downcast obj2
à PetDog
depuis obj2 est référencé à Dog
et ne pas avoir accès à dogName();
méthode
( (PetDog)obj2).dogName();
Pourquoi est-ce que c'est si, que upcasting est automatique, mais downcasting doit être Manuel? Eh bien, vous voyez, l'upcasting ne peut jamais échouer.
Mais si vous avez un groupe de Chiens différents et souhaitez abattu un de leurs types, alors il y a une chance que certains de ces chiens sont en fait de différents types i.e., PetDog
, PoliceDog
, et le processus échoue, en lançant ClassCastException
.
C'est la raison pour laquelle vous devez downcast vos objets manuellement si vous avez référencé vos objets au type super class.
Note: ici par référencement signifie que vous ne modifiez pas l'adresse mémoire de vos objets lorsque vous le réduisez encore reste le même que vous êtes juste les grouper à type particulier dans ce cas
Dog
je sais que cette question posée très longtemps mais pour les nouveaux utilisateurs de cette question. S'il vous plaît lire cet article où contient une description complète sur upcasting, downcasting et l'utilisation de instanceof operator
-
il n'y a pas besoin de upcast manuellement, il se passe sur son propre:
Mammal m = (Mammal)new Cat();
égale àMammal m = new Cat();
-
mais les prévisions descendantes doivent toujours faire manuellement:
Cat c1 = new Cat(); Animal a = c1; //automatic upcasting to Animal Cat c2 = (Cat) a; //manual downcasting back to a Cat
pourquoi la upcasting est-elle automatique, mais la downcasting doit-elle être manuelle? Eh bien, vous voyez, l'upcasting ne peut jamais échouer. Mais si vous avez un groupe d'animaux différents et que vous voulez tous les réduire à un chat, alors il ya une chance, que certains de ces animaux sont en fait des chiens, et le processus échoue, en lançant ClassCastException. C'est là que devrait introduire une fonctionnalité utile appelé "instanceof" , qui teste si un objet est instance d'une Classe.
Cat c1 = new Cat();
Animal a = c1; //upcasting to Animal
if(a instanceof Cat){ // testing if the Animal is a Cat
System.out.println("It's a Cat! Now i can safely downcast it to a Cat, without a fear of failure.");
Cat c2 = (Cat)a;
}
pour plus d'information s'il vous plaît lire cet article
mieux vaut essayer cette méthode pour upcasting, il est facile de comprendre:
/* upcasting problem */
class Animal
{
public void callme()
{
System.out.println("In callme of Animal");
}
}
class Dog extends Animal
{
public void callme()
{
System.out.println("In callme of Dog");
}
public void callme2()
{
System.out.println("In callme2 of Dog");
}
}
public class Useanimlas
{
public static void main (String [] args)
{
Animal animal = new Animal ();
Dog dog = new Dog();
Animal ref;
ref = animal;
ref.callme();
ref = dog;
ref.callme();
}
}
peut-être que cette table vous aidera.
Appel de la méthode callme()
de la classe Parent
ou de la classe Child
.
Comme principe:
UPCASTING -- > Hiding
DOWNCASTING -- > Revealing
Parent: Voiture
Enfant: Figo
Voiture c1 = Nouvelle Figo ();
=====
Upcasting: -
Méthode: l'objet c1 se réfère aux méthodes de la classe (Figo - la méthode doit être dépassée) parce que la classe "Figo" est spécifiée avec "nouveau".
Variable d'Instance: L'objet c1 se réfère à la variable d'instance de la classe de déclaration ("Car").
quand Classe de déclaration est parent et l'objet est créé de l'enfant puis casting implicite se produit qui est"Upcasting".
======
Estimation descendante: -
Figo f1 = (Figo) c1; / /
Méthode: L'objet f1 se réfère à la méthode de classe (figo) car l'objet c1 initial est créé avec la classe "Figo". mais une fois que la coulée vers le bas est faite, les méthodes qui ne sont présentes que dans la classe "Figo" peuvent aussi être référées par la variable f1.
Variable d'Instance: L'objet f1 ne se référera pas à la variable d'instance de la classe de déclaration de l'objet c1 (classe de déclaration pour c1 is CAR) mais avec down casting il se référera aux variables d'instance de la classe Figo.
======
Utilisation: lorsque L'objet est de classe enfant et que la classe de déclaration est Parent et que la classe enfant veut accéder à la variable D'Instance de sa propre classe et non de classe parent, alors cela peut être fait avec "Downcasting".
upcasting moyens de coulée de l'objet à un supertype, alors que les moyens de passer un casting pour un sous-type.
en java, la mise à jour n'est pas nécessaire car elle se fait automatiquement. Et on l'appelle habituellement le casting implicite. Vous pouvez préciser à préciser à d'autres.
ainsi, écrit
Animal a = (Animal)d;
ou
Animal a = d;
conduit exactement au même point, et dans les deux cas sera exécuté le callme()
de Dog
.
Downcasting est plutôt nécessaire parce que vous avez défini a
comme objet de L'Animal. Actuellement , vous savez que c'est un Dog
, mais java n'a aucune garantie que c'est le cas. En fait à l'exécution il pourrait être différent et java lancera un ClassCastException
, si cela se produisait. Bien sûr, il n'est pas le cas de votre exemple d'échantillon. Si vous ne voulez pas lancer a
à Animal
, java ne peut même pas compiler l'application parce que Animal
n'a pas la méthode callme2()
.
dans votre exemple vous ne pouvez pas atteindre le code de callme()
de Animal
de UseAnimlas
(parce que Dog
l'écrase) à moins que la méthode serait comme suit:
class Dog extends Animal
{
public void callme()
{
super.callme();
System.out.println("In callme of Dog");
}
...
}
nous pouvons créer un objet à Downcasting. Dans ce type également. : l'appel de la classe de base des méthodes de
Animal a=new Dog();
a.callme();
((Dog)a).callme2();