"Hallo, Amigo! Het onderwerp van de les van vandaag is het verbreden en verkleinen van typeconversies. Je hebt lang geleden geleerd over het verbreden en verkleinen van primitieve typen. Op niveau 10. Vandaag gaan we het hebben over hoe het werkt voor referentietypen, dwz voorbeelden van klassen."

In feite is het allemaal vrij eenvoudig. Stel je de overervingsketen van een klasse voor: de klasse, zijn ouder, de ouder van de ouder, enz., helemaal terug naar de klasse Object. Omdat een klasse alle lidmethoden bevat van de klasse die hij overerft , kan een instantie van de klasse worden opgeslagen in een variabele waarvan het type dat van een van zijn ouders is.

Hier is een voorbeeld:

Code Beschrijving
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
Hier hebben we drie klassendeclaraties: Dier, Kat en Tijger. Kat erft dier. En Tiger erft Cat.
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger();
Animal animal = new Tiger();
Object obj = new Tiger();
}
Een Tiger-object kan altijd worden toegewezen aan een variabele waarvan het type dat van een van zijn voorouders is. Voor de Tiger-klasse zijn dit Cat, Animal en Object.

Laten we nu eens kijken naar verbredende en versmallende conversies.

Als we door een toewijzingsbewerking omhoog gaan in de overervingsketen (in de richting van de klasse Object), hebben we te maken met een verbredende conversie (ook wel upcasting genoemd). Als we door de keten naar het objecttype gaan, is er sprake van een vernauwende conversie (ook wel downcasting genoemd).

Omhoog gaan in de overervingsketen wordt verbreding genoemd, omdat het leidt tot een algemener type. Door dit te doen, verliezen we echter de mogelijkheid om de methoden aan te roepen die door overerving aan de klasse zijn toegevoegd.

Code Beschrijving
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;
}
Wanneer u het type vernauwt, moet u een typeconversie-operator gebruiken, dwz we voeren een expliciete conversie uit.

Dit zorgt ervoor dat de Java-machine controleert of het object echt het type overerft waarnaar we het willen converteren.

Deze kleine innovatie zorgde voor een veelvoudige vermindering van het aantal typecastfouten en verhoogde de stabiliteit van Java-programma's aanzienlijk.

Code Beschrijving
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
Beter nog, gebruik een  instantie van check
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();
}
En hier is waarom. Bekijk het voorbeeld links.

Wij (onze code) weten niet altijd met welk type object we werken. Het kan een object zijn van hetzelfde type als de variabele (Animal), of elk type afstammeling (Kat, Tijger).

Overweeg de doAllAction-methode. Het werkt correct, ongeacht het type object dat wordt doorgegeven.

Met andere woorden, het werkt correct voor alle drie de typen: dier, kat en tijger.

public static void main(String[] args)
{
Cat cat = new Tiger();
Animal animal = cat;
Object obj = cat;
}
Hier hebben we drie toewijzingsoperaties. Het zijn allemaal voorbeelden van verbredende conversies.

De operator type cast is hier niet nodig, omdat er geen controle nodig is. Een objectreferentie kan altijd worden opgeslagen in een variabele waarvan het type een van zijn voorouders is.

"Oh, het voorlaatste voorbeeld maakte alles duidelijk: waarom de controle nodig is en waarom typecasting nodig is."

"Ik hoop het. Ik wil uw aandacht vestigen op dit feit:"

Dit alles zorgt er niet voor dat een object op enigerlei wijze verandert! Het enige dat verandert, is het aantal methoden dat beschikbaar is om op een bepaalde referentievariabele te worden aangeroepen.

Met een variabele Cat kunt u bijvoorbeeld de methoden doAnimalActions en doCatActions aanroepen. Het weet niets van de doTigerActions-methode, zelfs niet als het naar een Tiger-object verwijst.

"Ja, ik snap het. Het was makkelijker dan ik dacht."