"Hej Amigo! Ämnet för dagens lektion är breddning och snävare typkonverteringar. Du lärde dig om breddning och snäva primitiva typer för länge sedan. På nivå 10. Idag ska vi prata om hur det fungerar för referenstyper, dvs. förekomster av klasser."

Faktum är att det hela är ganska enkelt. Föreställ dig en klasss arvskedja: klassen, dess förälder, föräldern till föräldern, etc., hela vägen tillbaka till klassen Object. Eftersom en klass innehåller alla medlemsmetoder i klassen den ärver , kan en instans av klassen sparas i en variabel vars typ är den för någon av dess föräldrar.

Här är ett exempel:

Koda Beskrivning
class Animal
{
public void doAnimalActions();
}class Cat extends Animal
{
public void doCatActions();
}class Tiger extends Cat
{
public void doTigerActions();
}
Här har vi tre klassdeklarationer: Djur, Katt och Tiger. Katt ärver djur. Och Tiger ärver Cat.
public static void main(String[] args)
{
Tiger tiger = new Tiger();
Cat cat = new Tiger();
Animal animal = new Tiger();
Object obj = new Tiger();
}
Ett Tiger-objekt kan alltid tilldelas en variabel vars typ är en av dess förfäder. För Tiger-klassen är dessa Cat, Animal och Object.

Låt oss nu ta en titt på bredda och minska konverteringar.

Om en tilldelningsoperation får oss att flytta uppåt i arvskedjan (mot klassen Object) så har vi att göra med en breddad konvertering (även känd som upcasting). Om vi ​​rör oss nedåt i kedjan mot objektets typ, är det en avsmalnande konvertering (även känd som nedkastning).

Att flytta upp i arvskedjan kallas breddning, eftersom det leder till en mer allmän typ. Men genom att göra det förlorar vi möjligheten att anropa metoderna som läggs till klassen genom arv.

Koda Beskrivning
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;
}
När du avgränsar typen behöver du använda en typkonverteringsoperator, dvs vi utför en explicit konvertering.

Detta gör att Java-maskinen kontrollerar om objektet verkligen ärver den typ vi vill konvertera det till.

Denna lilla innovation gav en mångfaldig minskning av antalet typgjutningsfel och ökade avsevärt stabiliteten hos Java-program.

Koda Beskrivning
public static void main(String[] args)
{
Object obj = new Tiger();
if (obj instanceof Cat)
{
Cat cat = (Cat) obj;
cat.doCatActions();
}}
Ännu bättre, använd en  instans av 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();
}
Och här är varför. Ta en titt på exemplet till vänster.

Vi (vår kod) vet inte alltid vilken typ av objekt vi arbetar med. Det kan vara ett objekt av samma typ som variabeln (Animal), eller någon avkomlig typ (Cat, Tiger).

Överväg doAllAction-metoden. Det fungerar korrekt, oavsett vilken typ av objekt som skickas in.

Med andra ord fungerar det korrekt för alla tre typerna: djur, katt och tiger.

public static void main(String[] args)
{
Cat cat = new Tiger();
Animal animal = cat;
Object obj = cat;
}
Här har vi tre uppdragsoperationer. Alla är exempel på bredda konverteringar.

Typgjutoperatorn behövs inte här, eftersom ingen kontroll är nödvändig. En objektreferens kan alltid lagras i en variabel vars typ är en av dess förfäder.

"Åh, det näst sista exemplet gjorde allt klart: varför kontrollen behövs och varför typgjutning behövs."

"Jag hoppas det. Jag vill uppmärksamma er på detta faktum:"

Inget av detta får ett objekt att förändras på något sätt! Det enda som ändras är antalet tillgängliga metoder för att anropas på en viss referensvariabel.

En Cat-variabel låter dig till exempel anropa metoderna doAnimalActions och doCatActions. Den vet ingenting om metoden doTigerActions, även om den pekar på ett Tiger-objekt.

"Japp, jag förstår det. Det var lättare än jag trodde att det skulle vara."