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:javaof
mvnw.cmd clean compile exec:java- Maak een nieuwe klasse aan genaamd
Customer. Zorg er ook voor dat deze klasse een propertynameheeft van het type String. - Maak in de Main klasse een variabele genaamd
customeraan, van het typeCustomer(de klasse die we net gemaakt hebben) met behulp van hetnewkeyword. - 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 genaamdcustomer2van het typeCustomer. Geef deze een andere naam, en print ook deze. - Breidt nu de
Customerklasse uit met eenlastNameproperty van typeStringen eencustomerNumberproperty van typeint. - Voeg aan
Customerook eenprintName()methode to. Deze methode heeft geen parameters nodig en magvoidreturnen. 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
Mainzie 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 zowelcustomeralscustomer2een van de nieuwe Constructors gaan gebruiken. - Verwijder in
Mainde regelscustomer.name = ...encustomer2.name=..., dit gebeurt nu namelijk al in de constructor. - Vervang in
MainookSystem.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
CreditCarden geef deze een private propertyint debt, geef deze getters en setters en een constructor waarin deze property is opgenomen. - Voeg nu een private property
creditcardvan typeCreditCardtoe aan deCustomerklasse, 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
CreditCardte 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 deCreditCardeen 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
VisaCardaan en zorg dat deze van de klasseCreditCardextends; - 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
VisaCardtoe te voegen:
public VisaCard(int debt) {
super(debt);
}
- We hebben nu een klasse
VisaCard, maak nu ook een klasseMasterCardaan en laat deze ookCreditCardextenden. - 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
CreditCardgemaakt 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 methodepayvan 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.