Hej! I dag vil vi se nærmere på et princip for objektorienteret programmering (OOP): arv. Vi vil også studere andre typer forhold mellem klasser: sammensætning og aggregering. Dette emne vil ikke være svært: du har allerede stødt på arv og eksempler på arv mange gange i tidligere lektioner. I dag vil det vigtigste være at styrke din viden, undersøge arvemekanismen mere detaljeret og igen gennemgå nogle eksempler. :) Nå, lad os gå!
Arv i Java og dets fordele
Som du sikkert husker, er arv en mekanisme, der lader dig beskrive en ny klasse baseret på en eksisterende klasse (overordnet klasse). Derved låner den nye klasse egenskaberne og funktionaliteten af den overordnede klasse. Lad os huske et eksempel på arv givet i tidligere lektioner:
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
public void gas() {
// Gas
}
public void brake() {
// Brake
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
Vi har et bestemt program, der involverer at arbejde med forskellige typer biler. Selvom du ikke er bilentusiast, ved du sikkert, at der findes rigtig mange typer biler i verden. :) Derfor vil vi adskille bilers fælles egenskaber i en fælles overordnet klasse kaldet Car
. Så hvad er fælles for alle biler, uanset deres type? Hver bil har et produktionsår, modelnavn og maksimal hastighed. Vi placerer disse egenskaber i felterne model
, maxSpeed
, og yearOfManufacture
. Hvad angår adfærd, kan enhver bil accelerere og bremse. :) Vi definerer denne adfærd i gas()
ogbrake()
metoder. Hvilke fordele giver det os? Først og fremmest reducerer det mængden af kode. Vi kan selvfølgelig undvære forældreklassen. Men da hver bil skal kunne accelerere og bremse, bliver vi nødt til at skabe gas()
og brake()
metoder i klasserne Truck
, Sedan
, F1Car
, SportsCar
og i hver anden bilklasse. Forestil dig, hvor meget ekstra kode vi skal skrive. Og glem ikke felterne model
, maxSpeed
, og yearOfManufacture
: Hvis vi slipper af med forældreklassen, bliver vi nødt til at oprette dem i hver bilklasse! Når vi har et par dusin bilklasser, bliver mængden af dubletkode virkelig alvorlig. Flytning af almindelige felter og metoder (også kaldet "tilstande" og "adfærd") til en overordnet klasse lader os spare en masse tid og plads. Hvis en type har unikke egenskaber eller metoder, som andre biltyper ikke har, er det ikke noget problem. Du kan altid oprette dem i en efterkommerklasse, adskilt fra alle andre.
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
Lad os se på Formel 1 racerbiler som et eksempel. I modsætning til deres "slægtninge" har de en unik adfærd - de tager et pit stop fra tid til anden. Det her generer os ikke. Vi har allerede beskrevet den almindelige adfærd i Car
forældreklassen, og den specifikke adfærd for efterkommerklasser kan føjes til disse klasser. Det samme er tilfældet med felter: Hvis en børneklasse har unikke egenskaber, erklærer vi roligt disse felter inde i børneklassen og holder op med at bekymre os. :) Muligheden for at genbruge kode er den største fordel ved arv. For programmører er det meget vigtigt ikke at skrive ekstra kode. Du vil støde på dette gentagne gange i dit arbejde. Husk noget andet vigtigt: Java har ikke multipel arv. Hver klasse arver kun én klasse. Vi vil tale mere om årsagerne til dette i fremtidige lektioner. For nu skal du bare huske det. Dette gør i øvrigt Java anderledes end nogle andre OOP-sprog. For eksempel understøtter C++ multipel nedarvning. Alt er mere eller mindre klart med arv. Lad os gå videre.
Sammensætning og aggregering
Klasser og objekter kan kædes sammen. Arv beskriver et "er-et" forhold. En løve er et dyr. Et sådant forhold udtrykkes let ved hjælp af arv, hvorAnimal
er forældreklassen og Lion
er barnet. Det er dog ikke alle forhold, der beskrives på denne måde. For eksempel er et tastatur bestemt relateret til en computer, men det er ikke en computer . Hænder er på en eller anden måde relateret til en person, men de er ikke en person. I disse tilfælde har vi en anden type forhold: ikke "er-en", men "har-en". En hånd er ikke en person, men er en del af en person. Et tastatur er ikke en computer, men er en del af en computer. En har-en relation kan beskrives i kode ved hjælp af sammensætning og aggregering. Forskellen ligger i forholdets "strenghed". Lad os give et simpelt eksempel: Vi har en Car
klasse. Hver bil har en motor. Derudover har hver bil passagerer. Hvad er den grundlæggende forskel mellem felterne Engine engine
og Passenger[] passengers
? Det faktum, at passageren A
sidder i en bil, betyder ikke, at passagererne B
ikke C
er i bilen. En bil kan svare til flere passagerer. Hvad mere er, hvis alle passagerer stiger ud af en bil, vil den stadig fungere problemfrit. Forholdet mellem Car
klassen og Passenger[] passengers
arrayet er mindre strengt. Det kaldes aggregering . Det giver endnu et godt eksempel på aggregering. Antag, at vi har en Student
klasse og enStudentGroup
klasse. En studerende kan tilslutte sig flere studenterorganisationer: en fysikklub, en Star Wars-fanklub og/eller en komedieklub for studenter. Komposition er en strengere form for forhold. Når du bruger komposition, er et objekt en del af et eller andet objekt og kan ikke tilhøre et andet objekt af samme type. Det enkleste eksempel er en bilmotor. En motor er en del af en bil og kan ikke være en del af en anden bil. Som du kan se, er deres forhold meget strengere end forholdet mellem Car
og Passengers
.
GO TO FULL VERSION