"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 |
---|---|
|
Här har vi tre klassdeklarationer: Djur, Katt och Tiger. Katt ärver djur. Och Tiger ärver Cat. |
|
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 |
---|---|
|
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 |
---|---|
|
Ännu bättre, använd en instans av check |
|
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. |
|
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."
GO TO FULL VERSION