CodeGym /Cours /Bases de Java /Conversion de types. Conversions avec élargissement et ré...

Conversion de types. Conversions avec élargissement et réduction

Bases de Java
Niveau 4 , Leçon 3
Disponible

« Salut, Amigo ! Le thème de la leçon d'aujourd'hui est les conversions avec élargissement et réduction pour les types de référence. Tu as découvert l'élargissement et la réduction des types primitifs il y a longtemps. Au niveau 10. Aujourd'hui, nous allons parler de la façon dont cela fonctionne pour les types de référence, à savoir les instances de classes. »

En fait, tout cela est très simple. Imagine la chaîne d'héritage d'une classe : la classe, son parent, le parent du parent, etc., jusqu'à arriver à la classe Object. Comme une classe contient toutes les méthodes membres de la classe dont elle hérite, une instance de la classe peut être enregistrée dans une variable dont le type est celui de n'importe lequel de ses parents.

Voici un exemple :

Code Description
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
Ici, nous avons trois déclarations de classe : Animal, Cat et Tiger. Cat hérite d'Animal. Et Tiger hérite de Cat.
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger(); Animal animal = new Tiger(); Object obj = new Tiger();
}
Un objet Tigre peut toujours être affecté à une variable dont le type est celui d'un de ses ancêtres. Pour la classe Tigre, il s'agit de Cat, Animal et Object.

Maintenant, nous allons nous pencher sur les conversions avec élargissement et réduction.

Si une opération d'affectation nous fait remonter la chaîne d'héritage (en direction de la classe Object), nous avons affaire à une conversion avec élargissement (ce qu'on appelle également transtypage ascendant). Si on descend la chaîne dans la direction du type de l'objet, il s'agit d'une conversion avec réduction (ce qu'on appelle également transtypage descendant).

Remonter la chaîne d'héritage est appelé élargissement, car cela conduit à un type plus général. Toutefois, ce faisant, nous perdons la possibilité d'appeler les méthodes ajoutées à la classe par héritage.

Code Description
public static void main(String[] args)
{
Object obj = new Tiger();
Animal animal = (Animal) obj; Cat cat = (Cat) obj; Tiger tiger = (Tiger) animal; Tiger tiger2 = (Tiger) cat;
}
Lorsque tu réduis le type, tu dois utiliser un opérateur de conversion de type, c'est-à-dire que nous effectuons une conversion explicite.

Nous obligeons ainsi la machine Java à vérifier si l'objet hérite vraiment du type dans lequel nous voulons le convertir.

Cette petite innovation a permis une réduction considérable du nombre d'erreurs de conversion, et a augmenté de manière significative la stabilité des programmes Java.

Code Description
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
Mieux encore, utilise une vérification  instanceof
public static void main(String[] args)
{
Animal animal = new Tiger();
doAllAction(animal);

Animal animal2 = new Cat();
doAllAction(animal2);

Animal animal3 = new Animal();
doAllAction(animal3);
}

public static void doAllAction(Animal animal)
{
if (animal instanceof Tiger)
{
Tiger tiger = (Tiger) animal;
tiger.doTigerActions();
}

if (animal instanceof Cat)
{
Cat cat = (Cat) animal;
cat.doCatActions();
}

animal.doAnimalActions();
}
Et voilà pourquoi. Regarde un peu l'exemple à gauche.

Nous (et notre code) ne savons pas toujours avec quel type d'objet nous travaillons. Cela pourrait être un objet du même type que la variable (Animal), ou n'importe lequel des types descendants (Cat, Tiger).

Prenons la méthode doAllAction. Elle fonctionne correctement, quel que soit le type d'objet passé.

En d'autres termes, elle fonctionne correctement pour les trois types : Animal, Cat et Tiger.

public static void main(String[] args)
{
Cat cat = new Tiger(); Animal animal = cat; Object obj = cat;
}
Ici, nous avons trois opérations d'affectation. Toutes sont des exemples de conversion avec élargissement.

Pas besoin d'opérateur de conversion de type ici, car aucune vérification n'est nécessaire. Une référence d'objet peut toujours être stockée dans une variable dont le type est un de ses ancêtres.

« Oh, l'avant-dernier exemple rend tout cela clair : pourquoi le contrôle est nécessaire, et pourquoi la conversion de type est nécessaire. »

« J'espère bien. Je tiens à attirer ton attention sur ce fait : »

Rien de tout cela ne cause le moindre changement pour l'objet ! La seule chose qui change est le nombre de méthodes disponibles à l'appel sur une variable de référence particulière.

Par exemple, une variable Cat te permet d'appeler les méthodes doAnimalActions et doCatActions. Elle ne sait rien au sujet de la méthode doTigerActions, même si elle pointe vers un objet Tiger.

« Oui, je comprends ça. C'est plus facile que je l'imaginais. »

Commentaires (4)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Romain niveau 26, Paris, France
15 décembre 2020
Je crois qu'il y a une contradiction entre ce qui est dit ici et ce qui est dit au paragraphe 5) de la leçon 1 du niveau 12. Ici on nous dit qu'il y a conversion avec élargissement lorsque l'on remonte la chaîne d'héritage et conversion avec réduction lorsqu'on la descend. Extrait de la leçon : Remonter la chaîne d'héritage est appelé élargissement, car cela conduit à un type plus général. Toutefois, ce faisant, nous perdons la possibilité d'appeler les méthodes ajoutées à la classe par héritage. Alors que dans la leçon du niveau 12 on nous présentait le contraire, pour rappel nous avions une classe de base nommée "Vache" et une classe dérivée nommée "Baleine" et il était indiqué, en §5), qu''instancier un objet de la classe dérivée dans une variable du type de la classe de base était une conversion avec réduction, alors que nous remontons la chaîne. Ceci en le justifiant du fait qu'on ne pouvait alors n'appeler que des méthodes du type de la variable (mais grâce aux liaisons tardive, §4), la méthode appelée correspondait à celle de l'objet référencé dans la variable). Et grâce à cette justification je comprenais que l'on nomme cela une conversion avec réduction. Mais maintenant semble être dit le contraire, qu'en pensez vous ? Au passage dans les liens utiles du professeur qui suivent à ce niveau il y a une explication supplémentaire à ce sujet et ils vont dans le sens présenté ici.
John Squirrels niveau 41, San Francisco, Poland
15 décembre 2020
Thanks for reaching out. We will recheck it and come back to you with the answer/solution/feedback. Merci
VertOurs niveau 15, Paris, France
24 juin 2021
du nouveau sur ce sujet?
Banak niveau 29, Saint-Gratien, France
26 novembre 2020
cool