We schrijven een bestelsysteem. We kunnen gewone bestellingen en internationale bestellingen plaatsen. Voor geïmporteerde producten wordt een extra toelage van 10% aangerekend, maar is er wel korting voor grote bestellingen. We willen de prijzen van onze producten niet publiek zichtbaar maken, want dat verhindert prijsafspraken.
Schrijf een klasse Bestelling met een uint
property Aantal
en een double
privé-attribuut basisPrijs
. Voorzie ook een overschrijfbare property TotaalPrijs
, namelijk het aantal maal de basisprijs. Schrijf daarna een subklasse InternationaleBestelling
die de totaalprijs bepaalt door de basisprijs met 10% te verhogen, maar vanaf 100 stuks een vlakke korting van 1000 euro toepast. Dit zal niet meteen werken! Doe een zo klein mogelijke aanpassing om het toch te doen werken.
Schrijf een methode DemonstreerBestellingen
in de klasse Overerving
. Hierin vraag je of de gebruiker een gewone of internationale bestelling wil plaatsen, vraag je om het aantal en de basisprijs en toon je dan de totaalprijs.
We schrijven software om bestellingen van pizza's op te volgen. Deze software spreekt met andere software, bijvoorbeeld van Deliveroo of Uber Eats. We willen niet dat die diensten iets kunnen aanpassen aan de ingrediënten van onze pizza's, maar we willen wel zelf wel allerlei pizza's kunnen samenstellen.
Je krijgt volgende klasse Pizza
:
Schrijf nu twee klassen Margarita
en Veggie
die overerven van Pizza
, met basisprijs 5 en 6. Bij constructie krijgt een Margarita sowieso "mozzarella" toegevoegd aan de lijst met ingrediënten en krijgt een Veggie sowieso "tofu" en "spinazie", maar geen "kaas". Je moet hierbij een aanpassing doen aan Pizza
, maar hou ze zo klein mogelijk. Het blijft de bedoeling dat een pizza standaard ook kaas bevat, dus schrijf je code zodat de veggie pizza dit ingrediënt verwijdert. Schrijf een demonstratiemethode DemonstreerPizzas
in de klasse Overerving
.
We willen een digitale menukaart tonen in een online restaurant. Op deze kaart verschijnen gerechten in een standaardformaat. Kindergerechten volgen hetzelfde formaat, maar verschijnen in kleur.
Schrijf een klasse Gerecht
met properties Naam
en Prijs
(deze laatste van type double
)
De methode ToonOpMenu
print de naam, gevolgd door 3 tabs, gevolgd door de prijs
Schrijf een kindklasse KinderGerecht
Dit werkt hetzelfde als een gewoon gerecht, maar de weergave op het menu gebruikt een willekeurige kleur. Als we bijvoorbeeld het aantal tabs aanpassen naar 5, moet KinderGerecht zonder aanpassingen mee volgen.
Je kan een willekeurige kleur krijgen door een willekeurig getal tussen 1 en 15 te bepalen en dat dan te casten naar een waarde van de enum ConsoleColor
.
Maak een methode DemonstreerGerechten
in de klasse Overerving
. Hierin maak je een lijst met minstens 4 gerechten (waarvan minstens 2 kindergerechten) naar keuze en doorloop je de lijst zodat elk gerecht getoond wordt op het menu.
Tabs zijn eigenlijk niet ideaal. Zoek, als je sneller klaar bent, uit hoe je stringformattering kan gebruiken om de naam van elk gerecht met exact 35 tekens weer te geven.
In de volgende stappen, zullen we SchoolAdmin verder uitbouwen. Volgend diagram toont het hele project na al deze wijzigingen:
Voorzie Persoon
en Cursus
van een eigen versie van Equals. Hiermee zullen we later nagaan dat een van deze objecten niet dubbel voorkomt in de lijst met geregistreerde objecten.
Een persoon is gelijk aan een andere persoon met hetzelfde ID. Je hoeft hier niet na te gaan dat de objecten van exact hetzelfde type zijn. In plaats daarvan kan je schrijven: if (obj is Person) { ... }
Een cursus is gelijk aan een andere cursus met hetzelfde ID.
Voorzie ook overal een hash code volgens de vuistregel in de cursus.
ToString
Voorzie Persoon
van een ToString
methode die een resultaat van volgende vorm toont:
Voorzie in één keer een property Leeftijd
die berekend wordt aan de hand van de huidige datum.
Zorg dat de concrete klassen hier ook het statuut van de persoon aan koppelen, bijvoorbeeld:
Doe dit niet met GetType
, want dan is de schrijfwijze anders. Doe het met de hand per klasse.
Je hebt momenteel volgende statische properties voor (immutable) lijsten met personen:
AllePersonen
AlleLectoren
AlleStudenten
AllePersoneel
AlleAdministratiefPersoneel
Het is niet ideaal om al deze lijsten te hebben. Elke persoon wordt nu op twee of drie plaatsen bijgehouden, dus als je het systeem zou aanpassen om personen te verwijderen, moet je er aan denken dat op twee of drie plaatsen te doen. Als je klassen zoals Gastlector
, Uitwisselingsstudent
of Roosterverantwoordelijke
zou toevoegen, zou je dat zelfs op nog meer plaatsen moeten doen.
Vervang daarom de lijsten voor de subklassen van Persoon
zodat er geen achterliggend attribuut wordt bijgehouden. In plaats daarvan, moet de lijst met personen "on-the-fly" berekend worden. Met andere woorden, je moet nog steeds een getter AlleLectoren
enzovoort voorzien, maar deze verzamelt alle lectoren door AllePersonen
te doorlopen. Gebruik hier opnieuw het woordje is
dat we bij Equals
hebben gebruikt.
VakInschrijving
In je huidige code heeft de klasse Student
een lijst vakInschrijvingen
. Zo wordt een student gelinkt aan de cursussen die hij of zij volgt. Dit is niet ideaal, want in werkelijkheid willen we ook vaak te weten komen welke studenten in een bepaalde cursus zijn ingeschreven. We moeten dus in twee richtingen kunnen gaan.
Een mogelijke oplossing: voorzie de klasse VakInschrijving
van een (immutable) lijst AlleVakInschrijvingen
. Zo hoef je geen data dubbel bij te houden en kan je toch de functionaliteit verder uitbreiden. Schrap de huidige lijst met vakinschrijvingen in de klasse Student
. Voorzie ter vervanging daarvan een property student in de klasse VakInschrijving
die bijhoudt welke student bij de inschrijving hoort. Voorzie ook, in de klasse Student
, een property VakInschrijvingen
die "on-the-fly" berekent welke inschrijvingen bij de student in kwestie horen. Voorzie ook een property Cursussen
. Voorzie bovendien in de klasse Cursus een property VakInschrijvingen
en een property Studenten
. Al deze properties zijn onveranderlijke lijsten.
Je zal ten slotte de lijst met studenten uit de klasse Cursus
moeten verwijderen. Dit vraagt een aantal logische aanpassingen. In de methode DemonstreerCursussen
mag je code om studenten te associëren met een cursus verwijderen.
Momenteel bestaat een studieprogramma gewoon uit een vlakke lijst cursussen. Dat stemt niet goed overeen met de werkelijkheid. In werkelijkheid wordt een cursus in een bepaald semester ingepland. Eén manier om dit voor te stellen: vervang de vlakke lijst met cursussen door een Dictionary
met cursussen als keys en getalwaarden (semesters) als values. Doe deze aanpassing in je code. Je zal hiervoor je demonstratiecode moeten aanpassen. Zorg dat communicatie bij de opleiding programmeren in het eerste semester staat, maar bij de opleiding systeem- en netwerkbeheer in het tweede semester. Alle andere vakken staan overal in het eerste semester.
De demonstratiemethodes hebben bijna overal objecten aangemaakt door ze te "hard coden". Dat wil zeggen dat de instructies C# code zijn en niet gewijzigd kunnen worden eens je programma gecompileerd is. In een echte systeem voor schoolbeheer zou het administratief personeel voortdurend nieuwe entiteiten kunnen toevoegen aan het systeem.
Voorzie daarom vier nieuwe mogelijkheden in je keuzemenu: "student toevoegen", "cursus toevoegen", "vakinschrijving toevoegen" en "inschrijvingsgegevens tonen". De eerste drie vragen om de nodige gegevens om een object van een van deze klassen aan te maken. De laatste toont eerst alle studenten in het systeem, dan alle cursussen, dan alle inschrijvingen. Zorg ook dat je menu opties presenteert in een oneindige lus, zodat je je methodes samen kan testen.
Onderstaande screenshot toont een voorbeeldinteractie (enkel de nieuwe opties zijn getoond om plaats te sparen):