4535 Arv med monster
Ett sätt att undvika att skriva samma kod flera gånger är att använda arv. Nedan sker en demonstration med en spelarklass samt några monsterklasser. Monstren flyttar sig på samma vis i båda projekten.
Projekt med monster som använder arv, på GitHub
Förkunskaper
Klassdiagram utan arv
Klasserna Player, Troll, Elf och Phoinx ärver från klassen MonoBehavior. Pilen i klassdiagrammet ovan visar detta.
Snabbguide till klassdiagram
Snabbguide till klassdiagram, se diagram nedan.
I den översta rutan står klassens namn.
I nästa ruta är objektvariablerna uppräknade.
I sista rutan är metoderna uppräknade.
Objektvariabler och metoder föregås av synlighet. Tecknen har följande betydelse.
- (-) betyder private
- (#) betyder protected
- (+) betyder public
Klassens namn
- -objektvariabel : datatyp
- -objektvariabel_2: datatyp
- +Metod() : returdatatyp
- +Metod(parameter: datatyp) : returdatatyp
Steg 1 - Gemensamt
Klasserna Player, Troll, Elf och Phonix har alla objektvariablerna rb och speed gemensamma.
Dessa objektvariabler kommer att flyttas till klassen Actor.
Metoden Start() finns också i klasserna Player, Troll, Elf och Phonix. Innehållet i metoden är delvis gemensamt. Denna metod flyttas också till klassen Actor.
Metoden FixedUpdate() finns också i samtliga klasser men dess innehåll skiljer sig åt så den flyttar vi inte till klassen Actor.
Det nya klassdiagrammet blir som nedan.
Objektvariablerna är protected i Actor istället för private. Detta för att de ska finnas tillgängliga i ärvande klasser. På samma sätt för metoden Start().
Start() i gamla Player
private void Start()
Start() i Actor
protected virtual void Start()
// samma innehåll som i gamla Player
protected för att metoden ska synas i klasser som ärver från Actor.
virtual för att metoden ska kunna ersättas av en ny i ärvande klasser.
Start i nya Player med arv
protected override void Start()
{
// call Start() in super class Actor
base.Start();
tag = "Player";
}
override för att markera att metoden ersätter Start() i superklassen Actor.'
base.Start() för att anropa Start() i Actor.
Steg 2 - gemensamt
I klassdiagrammen för Troll, Elf och Phonix kan man se att de alla har objektvariabeln direction
. Därtill har de följande metoder gemensamt: Start(), FixedUpdate(), OnCollisionEnter2D(), OnCollisionStay2D(), SnapToGrid(), SnapToGridX() och SnapToGridY(). Dessa metoder samt objektvariabeln direction flyttar vi till den nya klassen Monster. I Monster ges objektvariabler och metoder synligheten protected
för att de skall kunna användas i ärvande klasser.
Lägger också till metoden SelectDiretion() för att OnCollisionEnter2D() och OnCollisionStay2D() ska vara mer lika sina motsvarigheter i Troll, Elf och Phonix.
Fullständigt klassdiagram visas nedan. En metod som finns i en superklass tas bara med i en subklass om den har nytt innehåll.
Koden i gamla Troll har i princip flyttats till Monster.
Det är i huvudsak sättet att välja riktning som skiljer Troll från Elf.
Däremot Phonix skiljer sig mer från både Troll och Elf.
Nya
Gamla
Kod för gamla Phonix på GitHub
Intressanta metodanrop
FixedUpdate() i Troll
Följande händer:
Metoden FixedUpdate() anropas på ett objekt av klassen Troll.
FixedUpdate() finns inte implementerad (skriven) i klassen Troll.
Den ärvda metoden från Monster anropas istället.
Detta kallas för sen bindning.
OnCollisionStay2D() i Troll
Följande händer:
Metoden OnCollisionStay2D() anropas på ett objekt av klassen Troll.
OnCollisionStay2D() finns inte implementerad i klassen Troll.
Den ärvda metoden från Monster anropas istället.
Så här långt är det väldigt likt exemplet ovan.
Koden för OnCollisionStay2D() i Monster återges nedan.
protected virtual void OnCollisionStay2D(Collision2D collision)
{
SelectDirection();
SnapToGrid();
}
Först anropas metoden SelectDirection(), men inte den i Monster utan den i Troll eftersom anropet började på ett objekt av klassen Troll.
Sedan anropas metoden SnapToGrid() i Monster eftersom den inte finns i Troll.
Övning på arv
Alternativ 1.
Skriv om ett av dina projekt så att arv används i större utsträckning. Ett lämpligt projekt är Cheese Gril.
Alternativ 2.
Lägg till fler monster som rör sig på andra sätt. Antingen i projektet som visats ovan eller i ett eget projekt. Arv ska användas.
Alternativ 3.
Egen idé om projekt med arv.