- Een child-object past in een variabele of lijst van het parent-type. Via die variabele kan je enkel wat in de parent staat; welke
overridedraait, beslist het echte object (uitleg). - Staat een methode
virtualofabstractin de parent, roep ze dan gewoon op. Eenis-test per soort is net wat polymorfisme overbodig maakt (uitleg). - Iets wat enkel een child heeft, bereik je met pattern matching:
if (dier is Koe koe) koe.GeefMelk();test en zet om in één keer (uitleg). - Een cast met haakjes zoals
(Koe)diercrasht als het geen koe is.asgeeft dannull: controleer daarop voor je verdergaat (uitleg).
Voorspel de uitvoer: wie neemt het woord? (Essential)
Eerste les in de aula. Je project heet Aula en heeft drie klassen, elk in een eigen bestand:
internal class Persoon
{
public string Naam { get; set; }
public virtual void StelVoor()
{
Console.WriteLine($"Ik ben {Naam}.");
}
public virtual void Groet()
{
Console.WriteLine("Hallo.");
}
}internal class Student : Persoon
{
public override void StelVoor()
{
Console.WriteLine($"Ik ben {Naam}, eerstejaars.");
}
}internal class Lector : Persoon
{
public string Vak { get; set; }
public override void StelVoor()
{
Console.WriteLine($"Ik ben {Naam} en ik geef {Vak}.");
}
public void Groet()
{
Console.WriteLine("Goeiemorgen, aula!");
}
}Deel 1. Schrijf op papier wat dit programma toont, lijn per lijn. Typ de code pas daarna over en vergelijk.
Persoon vooraan =
new Lector() { Naam = "Peeters", Vak = "programmeren" };
Persoon achteraan = new Student() { Naam = "Lotte" };
vooraan.StelVoor();
achteraan.StelVoor();
vooraan.Groet();
Lector peeters =
new Lector() { Naam = "Peeters", Vak = "programmeren" };
peeters.Groet();
Console.WriteLine(vooraan is Persoon);
Console.WriteLine(vooraan is Lector);
Console.WriteLine(achteraan is Lector);
Lector lector = achteraan as Lector;
Console.WriteLine(lector == null);
Console.WriteLine(achteraan.GetType().Name);
if (vooraan is Lector l && l.Vak == "programmeren")
{
Console.WriteLine("Dat wordt C#.");
}Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 2. Elk van deze vijf stukjes komt apart onderaan het programma uit deel 1. Compileert het niet, crasht het tijdens het uitvoeren, of werkt het? En waarom?
Console.WriteLine(vooraan.Vak); // Aobject iemand = achteraan; // B
iemand.StelVoor();Lector nieuw = new Persoon(); // Cif (!achteraan is Lector) // D
{
Console.WriteLine("Geen lector.");
}Lector fout = (Lector)achteraan; // EDeze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 3. De compiler gaf bij Lector een waarschuwing. Welke? Herstel ze. Wat toont de derde regel van deel 1 nu?
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
- Het type van de variabele bepaalt wat je mag oproepen. Het echte object bepaalt welke
overridedraait, maar enkel als de methodevirtualofabstractis én de childoverrideschrijft. - Een compileerfout zie je meteen. Een foute cast zie je pas als het programma loopt, en dan crasht het.
asenisvermijden die crash. - Zie Polymorfisme, Het as keyword en Volgorde van bewerkingen met is en as.
Een eigen huis (Essential)
In UML naar code (hoofdstuk 15) maakte je een Huis dat zijn kamers zelf aanmaakt. Nu krijgt elke kamer een prijs, en kan een huis zoveel kamers krijgen als je wil.
- Een
Kamerheeft eenOppervlakte(in vierkante meter, eenint), eenNaamen eenPrijs.Prijsheeft enkel eenget, zonder instantievariabele erachter: degetgeeft gewoon een getal terug of rekent het uit. Een gewone kamer kost 400 euro. Childs vanKameroverschrijvenPrijs. - Maak minstens deze childs:
Badkamer: kost 500 euro.Gang: kost 10 euro per vierkante meter.Salon: kost 300 euro, of 500 euro als er een schouw is. Of er een schouw is, houd je bij in eenbool-propertyHeeftSchouw.
- Een
Huisheeft een private lijst van kamers en deze methoden:VoegKamerToe: voegt de kamer toe die je meegeeft.BerekenPrijs: geeft de totale prijs van alle kamers terug.ToonOverzicht: toont van elke kamer de naam en de prijs, en daaronder het totaal.
Testcode. Je code werkt als je exact deze uitvoer krijgt.
Huis huis = new Huis();
huis.VoegKamerToe(new Salon() { Naam = "Salon", HeeftSchouw = true });
huis.VoegKamerToe(new Gang() { Naam = "Gang", Oppervlakte = 20 });
huis.VoegKamerToe(new Badkamer() { Naam = "Badkamer" });
huis.VoegKamerToe(new Kamer() { Naam = "Slaapkamer" });
huis.ToonOverzicht();Salon: 500 euro
Gang: 200 euro
Badkamer: 500 euro
Slaapkamer: 400 euro
Totaal: 1600 euro
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
- De lijst bevat
Kamer-variabelen, maar in de heap zitten salons, gangen en badkamers. OmdatPrijsvirtualis, geeftkamer.Prijsin dezelfde lus telkens de prijs van de echte kamer. - Een property zonder
seten zonder instantievariabele kan gewoon iets uitrekenen. Zet iemand laterHeeftSchouwoptrue, dan klopt de prijs van het salon vanzelf.
Luchtvaartshow (Essential, GPT)
Op een luchtvaartshow doet elk toestel zijn eigen nummertje: een dubbeldekker, een straaljager, een helikopter en een luchtballon. Je werkt met overerving, polymorfisme, base, een Dictionary en static.

De basisklasse Vliegtoestel
- Een property
ModelNaammet een privateset, en een constructor die de modelnaam krijgt. - Een
virtualmethodeVlieg()dieHet vliegtoestel [ModelNaam] stijgt op.toont. - Een private static
Dictionary<string, Vliegtoestel>als register: elk nieuw toestel zet zichzelf erin vanuit de constructor, metAdden de modelnaam als sleutel. Een modelnaam mag dus maar één keer voorkomen: een tweede keer dezelfde naam geeft eenArgumentException. - Een static methode
ToonRegister()die van elk toestel in het register de modelnaam en het type toont. - Een static methode
Show()die elk toestel uit het register laat vliegen.
De childs
Straaljager:Vlieg()toont enkelDe straaljager [ModelNaam] doorbreekt de geluidsmuur!Helikopter: heeft een extra propertyRotorSnelheid, die je via de constructor meegeeft.Vlieg()roept eerstbase.Vlieg()op en toont daarnaDe helikopter [ModelNaam] draait met een rotorsnelheid van [RotorSnelheid] toeren per minuut.Luchtballon:Vlieg()toont enkelDe luchtballon [ModelNaam] zweeft traag met de wind mee.
De dubbeldekker heeft geen eigen klasse: dat is een gewoon Vliegtoestel.
Testcode. Je code werkt als je exact deze uitvoer krijgt.
Vliegtoestel dubbeldekker = new Vliegtoestel("Tiger Moth");
Straaljager straaljager = new Straaljager("F-16");
Helikopter helikopter = new Helikopter("Agusta A109", 380);
Luchtballon ballon = new Luchtballon("Zonnebloem");
Vliegtoestel.ToonRegister();
Vliegtoestel.Show();
try
{
Straaljager tweede = new Straaljager("F-16");
}
catch (ArgumentException)
{
Console.WriteLine("Die modelnaam staat al in het register.");
}Geregistreerde toestellen:
Model: Tiger Moth, Type: Vliegtoestel
Model: F-16, Type: Straaljager
Model: Agusta A109, Type: Helikopter
Model: Zonnebloem, Type: Luchtballon
De show begint!
Het vliegtoestel Tiger Moth stijgt op.
De straaljager F-16 doorbreekt de geluidsmuur!
Het vliegtoestel Agusta A109 stijgt op.
De helikopter Agusta A109 draait met een rotorsnelheid van 380 toeren per minuut.
De luchtballon Zonnebloem zweeft traag met de wind mee.
Die modelnaam staat al in het register.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
- Omdat de childs met
base(modelNaam)de constructor vanVliegtoesteloproepen, registreren ze zichzelf vanzelf. Het register staat één keer in de parent. Showkent enkelVliegtoestel, en toch vliegt elk toestel op zijn manier. Komt er morgen eenZweefvliegtuigbij, dan verandert er aanShowniets.
Dierentuin advanced (Essential)
Werk verder aan je Dierentuin uit hoofdstuk 14, met Koe, Slang en Varken. Het menu krijgt er twee keuzes bij.
Deel 1. Keuze 5. Praten per soort: de gebruiker typt een soort (koe, slang of varken), en enkel de dieren van die soort zeggen iets. Staat er geen enkel dier van die soort in de lijst, of typt de gebruiker iets anders, dan toont het programma Geen dieren van die soort.
Schrijf daarvoor een methode static bool IsVanSoort(Dier dier, string soort) die met een switch en is zegt of het dier van die soort is. Zo heb je maar één lus nodig.
Deel 2. Keuze 6. Gifcontrole: Slang krijgt een bool-property Giftig. Maak in VulStartDieren de slang van 3 kg giftig, en zet er een tweede slang van 5 kg bij die niet giftig is. Keuze 6 toont elke giftige slang met haar gewicht, en daarna het aantal giftige slangen.
Een voorbeeld:
1. Dier verwijderen
2. Gemiddeld gewicht
3. Dieren praten
4. Opnieuw beginnen
5. Praten per soort
6. Gifcontrole
q. Stoppen
>5
Welke soort (koe, slang of varken)?
>slang
Sssssss
Sssssss
...
>5
Welke soort (koe, slang of varken)?
>giraf
Geen dieren van die soort.
...
>6
Giftige slang van 3 kg
Aantal giftige slangen: 1
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
- In deel 1 is
iseen ja-of-neevraag. Omzetten hoeft niet:Zegtstaat al inDier, en late binding kiest het juiste geluid. - In deel 2 kan het niet zonder omzetten:
Giftigbestaat enkel inSlang.dier is Slang slangtest en zet om in één keer, en dankzij&&wordtslang.Giftigenkel bekeken als het echt een slang is. - Zie Het is keyword en Pattern matching: is met een variabele.
Stevens dierenshow (Essential)
Stagiair Steven werkt verder aan de dierentuin van Dierentuin advanced. Voor de dierenshow moet elk dier één keer op het podium komen en praten, en daarna moet elke koe gemolken worden. Daarvoor gaf hij Koe een extra methode GeefMelk. De klassen zien er zo uit (in je project staat elke klasse in een eigen bestand; Giftig laat hij voor de show weg):
internal abstract class Dier
{
public int Gewicht { get; set; }
public abstract void Zegt();
}
internal class Koe : Dier
{
public override void Zegt()
{
Console.WriteLine("Moeeeh");
}
public void GeefMelk()
{
Console.WriteLine("De koe geeft een emmer melk.");
}
}
internal class Slang : Dier
{
public override void Zegt()
{
Console.WriteLine("Sssssss");
}
}
internal class Varken : Dier
{
public override void Zegt()
{
Console.WriteLine("Knor knor");
}
}Voor de show zelf vroeg Steven een A.I. om “een lus die bij elk soort dier het juiste doet”. Hij plakte dit in Main:
List<Dier> dieren = new List<Dier>();
dieren.Add(new Koe() { Gewicht = 600 });
dieren.Add(new Slang() { Gewicht = 3 });
dieren.Add(new Varken() { Gewicht = 110 });
dieren.Add(new Koe() { Gewicht = 550 });
foreach (Dier dier in dieren)
{
if (dier is Dier)
Console.WriteLine($"Op het podium: een dier van {dier.Gewicht} kg");
else if (dier is Koe)
((Koe)dier).GeefMelk();
switch (dier.GetType().Name)
{
case "Koe":
((Koe)dier).Zegt();
break;
case "Slang":
((Slang)dier).Zegt();
break;
}
}Deel 1. Het compileert zonder één waarschuwing. Voer het uit. Er wordt geen enkele koe gemolken. Waarom niet?
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 2. Ook het varken zegt niets. Waarom niet? En waarom had Steven die hele switch niet nodig?
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 3. Herschrijf de lus. Elk dier komt op het podium en praat, en elke koe geeft daarna melk. Gebruik geen cast met haakjes.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
is Dierop een element van eenList<Dier>is altijdtrue, tenzij het elementnullis. Test je in eenifmetelse ifop meerdere types, zet dan het meest specifieke type eerst.- Heeft elk object de methode al, omdat ze
virtualofabstractis in de parent, dan heb jeisniet nodig.isis voor wat enkel een child kan, zoalsGeefMelk. - Zie Het is keyword, Pattern matching: is met een variabele en de stagiair in Polymorfisme in de praktijk.
Stevens Pokédex (Essential)
Stagiair Steven houdt een pokedex bij: een lijst waarin elke Pokémon maar één keer mag staan. Om het kort te houden werkt hij met een ingekorte Pokemon-klasse, met een naam, een level en twee base-stats. Voor het vergelijken vroeg hij een A.I. om een Equals, en die zette hij in de klasse:
internal class Pokemon
{
public string Naam { get; private set; }
public int Level { get; private set; }
public int HP_Base { get; private set; }
public int Attack_Base { get; private set; }
public Pokemon(string naam, int level, int hpBase, int attackBase)
{
Naam = naam;
Level = level;
HP_Base = hpBase;
Attack_Base = attackBase;
}
public bool Equals(Pokemon andere)
{
return Naam == andere.Naam && Level == andere.Level
&& HP_Base == andere.HP_Base && Attack_Base == andere.Attack_Base;
}
}Om te testen schreef hij in Main:
Pokemon a = new Pokemon("Pikachu", 5, 35, 55);
Pokemon b = new Pokemon("Pikachu", 5, 35, 55);
Console.WriteLine($"a.Equals(b): {a.Equals(b)}");
List<Pokemon> pokedex = new List<Pokemon>();
pokedex.Add(a);
if (!pokedex.Contains(b))
{
pokedex.Add(b);
}
Console.WriteLine($"Aantal in de pokedex: {pokedex.Count}");
Pokemon[] team = new Pokemon[6];
team[0] = new Pokemon("Bulbasaur", 5, 45, 49);
team[1] = a;
bool zitInTeam = false;
for (int i = 0; i < team.Length; i++)
{
if (b.Equals(team[i]))
{
zitInTeam = true;
}
}
Console.WriteLine($"Pikachu zit in het team: {zitInTeam}");“De eerste regel toont True, dus mijn Equals werkt”, zegt hij.
Deel 1. Het compileert zonder één waarschuwing. Voer het uit. Waarom staan er twee Pikachu’s in de pokedex, terwijl a.Equals(b) True geeft? Dat het programma daarna crasht, is voor deel 2.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 2. Na die twee regels crasht het programma. Welke regel is de schuldige, en waarom?
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 3. Herschrijf de Equals van Steven zodat de pokedex en het team kloppen, en vergeet GetHashCode niet. Welke uitvoer verwacht je nu?
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
Deel 4. Nu je eigen Pokémon. Overschrijf Equals en GetHashCode in je Pokemon-klasse uit hoofdstuk 10, op dezelfde manier. Twee Pokémon zijn gelijk als hun naam, hun level en hun zes base-stats gelijk zijn. De _Full-stats vergelijk je niet: die worden uitgerekend uit de base-stats en het level.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
- Zonder
overrideis een methode met dezelfde naam en een andere parameter een overload. De compiler zegt daar niets van, en een test met tweePokemon-variabelen slaagt gewoon. Test daarom ook met de code die jeEqualsecht gaat gebruiken, zoalsContains. - De parameter van
Equalsis eenobject. Controleer eerst of het eenPokemonis: daarmee vang je ooknullop. - Zie Method overloading, De Equals() methode, Wat kan een List nog? en Is, as en polymorfisme: een krachtige bende.
Ganzenbord Dams Van Camp editie
Bordspelen zoals Ganzenbord of Monopoly zijn goede oefeningen voor polymorfisme. Het speelbord is een lijst van objecten, met elk vakje een object in die lijst. Sommige vakjes kunnen meer dan andere, dus de lijst bevat objecten van verschillende child-klassen met één basisklasse. Deze opgave komt uit het examen van de tweede zit in augustus 2021. Het grootste deel is herhaling van hoofdstuk 9 tot en met 12; het polymorfisme zit in het laatste stuk.
De kinderen van meneer Dams en Van Camp spelen graag Ganzenbord. Laatst vroegen ze zich af of mijn studenten eigenlijk ganzenbord zouden kunnen programmeren. “Uiteraard!” antwoordde meneer Dams. “Een vereenvoudigde versie, maar toch.” En hier zit je nu dus, met de basis van ganzenbord voor één speler. Geen flauw benul hoe ganzenbord werkt? Geen probleem, alles staat in de opgave.
Het spel. Eén speler probeert zo ver mogelijk te geraken op een rij van 10 vakjes. Sommige vakjes doen iets met de speler die erop belandt (bijvoorbeeld een stapje vooruit), andere doen niets. Het bord wordt bij de start van elk spel willekeurig aangemaakt. De speler rolt een dobbelsteen om te weten hoeveel vakjes zijn pion vooruit gaat, en verdient punten naarmate hij verder geraakt.
De klasse Dobbelsteen heeft een static methode Rol die een willekeurig getal teruggeeft: 1, 2 of 3.
De klasse Speelvakje heeft:
- Een int-property
BeweegVakjesmet een privateset: zoveel vakjes gaat de speler vooruit (positief) of achteruit (negatief) als hij op dit vakje belandt. - Een default constructor die
BeweegVakjeszo instelt:- 30% kans op +1 of +2
- 20% kans op -1 of -2
- 50% kans op 0
- Een
virtualmethodeToonVakjedie op de huidige plaats van de cursor de waarde vanBeweegVakjesschrijft. Is de waarde positief of 0, dan met een + ervoor, zoals +2 of +0. Een negatieve waarde toon je met de -, zoals -2.
De klasse Ganzenbord heeft:
- Een private lijst
speelvakjesmet 10Speelvakje-objecten, die de default constructor aanmaakt. - Een private instantievariabele
pionIndex: de index van het vakje waar de speler nu staat. - Een autoproperty
HuidigeScoredie standaard 0 is. - Een methode
BeweegPiondie eenintkrijgt en eenboolteruggeeft. - Een methode
TekenBorddie het bord op het scherm toont.
BeweegPion krijgt het getal dat de speler gerold heeft. pionIndex gaat zoveel vooruit, en dan:
- Is
pionIndex10 of meer, dan is de speler voorbij het laatste vakje en heeft hij gewonnen.HuidigeScoregaat 10 omhoog en de methode geefttrueterug. - Is
pionIndex9 of lager, dan kijk je in de lijst op welk vakje de speler beland is. DeBeweegVakjesvan dat vakje tel je op bijpionIndex. Op het nieuwe vakje gebeurt daarna niets meer, ook al zou je daar vooruit of achteruit moeten.- Komt
pionIndexzo onder 0, dan gaatHuidigeScore10 omlaag, komtpionIndexterug op 0 en geeft de methodefalseterug. - Ligt
pionIndextussen 0 en 9, dan geeft de methodefalseterug. - Is
pionIndex10 of meer, dan heeft de speler toch gewonnen:HuidigeScoregaat 10 omhoog en de methode geefttrueterug.
- Komt
TekenBord toont de 10 vakjes naast elkaar: het overloopt de lijst en roept van elk vakje ToonVakje op. Daarna overschrijft het op de plaats van de pion het cijfer met een T. Staat de speler op index 3, het vierde vakje, dan kan dat zo uitzien:
-1+2+1-T+0+0-2+1+1+0
Het eerste vakje heeft waarde -1, het tweede +2, het derde +1. Van het vierde zie je enkel het minteken, want op het cijfer staat de T. Daarna volgen +0 en +0, enzovoort.
De spellus in Main
- Maak een
Ganzenbord-object. - Herhaal tot de speler aan het einde is:
- Toon het bord met
TekenBord. - Rol met
Rol, en toon onder het bord bijvoorbeeldJe rolde 2. - Geef de worp aan
BeweegPion. Het resultaat bepaalt of de lus doorgaat. - Wacht tot de gebruiker op enter duwt, en maak dan het scherm leeg.
- Toon het bord met
- Toon op het einde de
HuidigeScore.
Polymorfisme. Werkt alles, maak dan een klasse KleurVakje die erft van Speelvakje. Zo’n vakje doet alles wat een gewoon vakje doet, maar ToonVakje toont de waarde in kleur: witte letters op een rode achtergrond als BeweegVakjes negatief is, anders zwarte letters op een groene achtergrond.
Geef Ganzenbord een tweede constructor die een bool krijgt: true vult de lijst met KleurVakjes, false met gewone Speelvakjes. Bij de start vraagt het programma of de speler de kleurenversie of de zwart-witversie wil spelen.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
TekenBordweet niet of een vakje gekleurd is. Het roeptToonVakjeop, en het echte object beslist hoe het eruitziet.KleurVakjeherhaalt de tekst niet: het zet de kleur, laatbase.ToonVakje()het werk doen en zet de kleur terug.- De tweede constructor bepaalt welke soort vakjes in de lijst komt. De rest van
Ganzenbordblijft hetzelfde.
Grand Theft Auto: San Andreas - Polymorfisme (Final Essentials, GPT)
Los Santos heeft een divers wagenpark. Het is jouw taak om een universeel bestuurssysteem te maken dat werkt voor elk voertuig, van sportwagens tot politiemotoren.
Stap 1: de abstracte klasse. Maak een abstracte klasse Voertuig met:
- een property
Merk(string); - een property
Snelheid(int), standaard 0, die enkelVoertuigen zijn childs kunnen aanpassen; - een abstracte methode
Beweeg(), die de snelheid instelt en de beweging toont; - een virtuele methode
ToonInfo(), dieDit is een voertuig van merk [Merk].toont.
Stap 2: de garage. Maak drie klassen die erven van Voertuig:
SportwagenBeweeg(): zetSnelheidop 150 en toontZOEF! De [Merk] scheurt over de snelweg met 150 km/u.ToonInfo(): toontEen glimmende sportwagen van [Merk]. Pas op voor krassen!
PantserwagenBeweeg(): zetSnelheidop 60 en toontBROEM... De [Merk] rijdt traag maar stopt voor niets of niemand.ToonInfo(): toontEen gepantserd voertuig van [Merk]. Kogelvrij!
PolitieMotor- Heeft een
bool-propertySireneAan, standaardfalse. Beweeg(): staat de sirene aan, dan zet hijSnelheidop 120 en toont hijWIEUWIEUWIEU! De [Merk] achtervolgt de verdachte met 120 km/u!Anders zet hijSnelheidop 50 en toont hijDe [Merk] patrouilleert rustig met 50 km/u.ToonInfo()overschrijft hij niet.
- Heeft een
Stap 3: het verkeer. Maak in Main een List<Voertuig> met deze voertuigen, in deze volgorde: een sportwagen Infernus, een politiemotor HPV-1000, een pantserwagen Rhino en een sportwagen Cheetah. Laat elk voertuig in één lus bewegen, en toon daarna in een tweede lus van elk voertuig de info.
Stap 4: de bankoverval. Toon Er is een bankoverval gemeld!. Zet bij elke politiemotor in de lijst de sirene aan, en laat daarna alle voertuigen opnieuw bewegen.
De uitvoer:
ZOEF! De Infernus scheurt over de snelweg met 150 km/u.
De HPV-1000 patrouilleert rustig met 50 km/u.
BROEM... De Rhino rijdt traag maar stopt voor niets of niemand.
ZOEF! De Cheetah scheurt over de snelweg met 150 km/u.
Een glimmende sportwagen van Infernus. Pas op voor krassen!
Dit is een voertuig van merk HPV-1000.
Een gepantserd voertuig van Rhino. Kogelvrij!
Een glimmende sportwagen van Cheetah. Pas op voor krassen!
Er is een bankoverval gemeld!
ZOEF! De Infernus scheurt over de snelweg met 150 km/u.
WIEUWIEUWIEU! De HPV-1000 achtervolgt de verdachte met 120 km/u!
BROEM... De Rhino rijdt traag maar stopt voor niets of niemand.
ZOEF! De Cheetah scheurt over de snelweg met 150 km/u.
Deze oplossing is afgeschermd.
Studenten krijgen de sleutel van hun lesgever. Heb je de sleutel al eens op dit toestel
gebruikt, dan verschijnt de oplossing hier vanzelf.
BeweegenToonInfostaan inVoertuig, dus de lussen roepen ze op zonder te vragen wat voor voertuig het is. DePolitieMotorzonder eigenToonInfokrijgt de tekst vanVoertuig.SireneAanbestaat enkel inPolitieMotor. Daar heb jeis PolitieMotor motorvoor nodig.Beweegisabstract: een nieuw soort voertuig kan niet vergeten te bewegen.