In deze opdracht gaan we leren hoe we inheritance kunnen gebruiken. Je kunt deze opdracht maken door het project te clonen of te downloaden naar jouw eigen computer via deze GitHub repository. De uitwerkingen staan op de branch uitwerkingen.
Je hebt IntelliJ IDEA en de JDK (Java Development Kit) versie 17 of hoger nodig - deze heb je beiden via de instructies op EdHub geïnstalleerd.
Klik op de groene play-knop voor de main-methode en kies 'Run...'.
Klik op de groene play-knop voor de MainTest-class in src/test/java en kies 'Run 'MainTest''.
Of, als je bekend bent met de terminal, kun je de applicatie runnen met:
./mvnw clean compile exec:java
of
mvnw.cmd clean compile exec:java
- Maak een nieuwe klasse aan genaamd
Customer
. Zorg er ook voor dat deze klasse een propertyname
heeft van het type String. - Maak in de Main klasse een variabele genaamd
customer
aan, van het typeCustomer
(de klasse die we net gemaakt hebben) met behulp van hetnew
keyword. - Na het aanmaken van deze nieuwe instantie kan je de
name
-property toewijzen, geef dit je eigen naam. - Je kan daarna als het goed is de naam printen door
System.out.println(customer.name);
daaronder te zetten. Als het goed is wordt nu je naam geprint. - Onder de
System.out.println(customer.name);
maak een tweede variabele genaamdcustomer2
van het typeCustomer
. Geef deze een andere naam, en print ook deze. - Breidt nu de
Customer
klasse uit met eenlastName
property van typeString
en eencustomerNumber
property van typeint
. - Voeg aan
Customer
ook eenprintName()
methode to. Deze methode heeft geen parameters nodig en magvoid
returnen. In de body van de methode zet jeSystem.out.println("Customer " + name);
- Maak twee Constructors. Een met de signature
(String, String)
en een met de signature(String, String, int)
. Tip: de ene constructor heeft dus 3 parameters, de andere 2 parameters. - In
Main
zie je nu een foutmelding staan bij()
-haakjes vannew Customer()
. De default Constructor is namelijk komen te vervallen, omdat je 2 custom Constructors hebt gemaakt. Je mag nu voor zowelcustomer
alscustomer2
een van de nieuwe Constructors gaan gebruiken. - Verwijder in
Main
de regelscustomer.name = ...
encustomer2.name=...
, dit gebeurt nu namelijk al in de constructor. - Vervang in
Main
ookSystem.out.println(customer.name);
enSystem.out.println(customer2.name);
door deprintName()
methode van die klassen aan te roepen
Een Customer moet natuurlijk kunnen betalen! Dit kan heel goed met een creditcard...
- Maak een klasse
CreditCard
en geef deze een private propertyint debt
, geef deze getters en setters en een constructor waarin deze property is opgenomen. - Voeg nu een private property
creditcard
van typeCreditCard
toe aan deCustomer
klasse, maak hier ook getters en setters voor en voeg de property toe aan beide constructors. - Pas ook de main methode aan om de 2 customers een
CreditCard
te geven.
Deze aanroep zou er dan ongeveer zo uit moeten zien:
Customer customer = new Customer("Frodo", "Balings", new CreditCard(100));
- Voeg een methode
void pay(int amount)
toe aan de CreditCard klasse. Deze methode moet deCreditCard
een nieuw bedrag geven gelijk aan het oude bedrag + amount (een CreditCard verzamelt namelijk schuld). Je kan nu in de main methode een betaling doen doorcustomer.getCreditCard().pay(10)
te doen, en de huidige schuld kun je printen doorSystem.out.println(customer.getCreditCard().getDebt());
te doen.
Er zijn 2 grote creditcard maatschappijen in de wereld, namelijk VisaCard en MasterCard. Wanneer we willen implementeren, zullen we hiervoor overerving moeten gebruiken.
- Maak een nieuwe klasse
VisaCard
aan en zorg dat deze van de klasseCreditCard
extends; - Je ziet dat de code niet compileert, dit komt doordat de super klasse (CreditCard) een constructor heeft, dus moet de subklasse VisaCard dit ook hebben.
Dit is op te lossen door een constructor aan
VisaCard
toe te voegen:
public VisaCard(int debt) {
super(debt);
}
- We hebben nu een klasse
VisaCard
, maak nu ook een klasseMasterCard
aan en laat deze ookCreditCard
extenden. - Nu we ervoor hebben gekozen om voor alle creditcards een implementatie te maken heeft het geen zin meer om toe te staan dat er een instantie van de super class
CreditCard
gemaakt kan worden. Maak deze klasseabstract
. - We zien nu in Main dat we geen nieuwe instantie meer kunnen maken van CreditCard. Geef daarom éen customer een VisaCard en de andere een MasterCard.
Doordat de methode pay
op CreditCard
zit, en VisaCard
en MasterCard
beide hiervan overerven, hebben ze ook beide automatisch de methode pay
tot hun beschikking! Je zult daarom ook zien dat customer.getCreditCard().pay(10)
nog steeds prima werkt.
Nu we een aparte klasse voor VisaCard
en MasterCard
hebben, kunnen we ook zorgen dat ze ander gedrag gaan vertonen. Stel VisaCard wil 10% korting geven op alle aankopen. In dat geval moeten we de pay
-methode overschrijven in de klasse VisaCard
. Doe dit als volgt:
@Override
public void pay(int amount) {
super.pay(amount);
}
- De aanroep naar
super.pay()
betekend hier dat de methodepay
van de super klasse (CreditCard) wordt aangeroepen. Zorg er hier voor dat het amount 10% lager wordt (door bijvoorbeeld (int)(amount * 0.9) te doen).
Je zult nu zien dat als je in Main zowel customer
als customer2
beide een andere creditcard geeft met een amount 0, en op beide pay
aanroept met het bedrag 100, de schuld op beide kaarten nu anders zal zijn.