• No results found

Java object georiënteerd programmeren

N/A
N/A
Protected

Academic year: 2022

Share "Java object georiënteerd programmeren"

Copied!
37
0
0

Bezig met laden.... (Bekijk nu de volledige tekst)

Hele tekst

(1)

Java object georiënteerd programmeren

Les10 – Overerving en polymorfisme

Kristien Van Assche

Academiejaar 2020-2021

(2)

Overerving en polymorfisme

2020 – Kristien Van Assche 2

(3)

new

this.

extends

super() instanceof

super.

private

protected public

this()

Recap: Java sleutelwoorden

(4)

Welk sleutelwoord gebruik je…

• om een object aan te maken van een klasse

• om methode van huidig object aan te spreken

• om veld van huidig object aan te spreken

• om klasse te laten overerven van andere klasse

• om default constructor van basisklasse aan te spreken

• om niet-default constructor van basisklasse aan te spreken

• om methode van basisklasse aan te spreken

• om veld van basisklasse aan te spreken

• om veld/methode af te schermen van alle andere klassen

• om veld/methode toegankelijk te maken voor zijn subklasse én alle andere klassen in zelfde package

• om veld/methode toegankelijk te maken voor iedere andere klasse, al dan niet in zelfde package

• Als je wil verhinderen dat je een object kan maken van een klasse

• Als je wil verhinderen dat je een subklasse kan maken van een klasse

new

this.method() extends

super(…)

super.method(), this.method() super.field, this.field

private protected

public

2020 – Kristien Van Assche

this.field super()

abstract final

(5)

//logische klasse

public class Persoon { private String naam;

private int leeftijd;

public int getLeeftijd() { return this.leeftijd;

}

public void verjaar() { this.leeftijd++;

}

public int telLeeftijdBij(int aantal) { for (int i = 0; i < aantal; i++) {

this.verjaar();

}

return leeftijd;

} //presentatieklasse

public class Console {

public static void main(String[] args) { Persoon p = new Persoon();

System.out.println(p.getLeeftijd());

p.verjaar();

System.out.println(p.telLeeftijdBij(5));

} }

0 6 Uitvoer:

Sleutelwoorden new & this

(6)

Sleutelwoord extends

//basisklasse

public class Persoon { private String naam;

private int geboortejaar;

… }

2020 – Kristien Van Assche

//presentatieklasse public class Console {

public static void main(String[] args) { Acteur a = new Acteur();

System.out.println(a);

} }

Acteur@68e26d2e Uitvoer:

//subklasse

public class Acteur extends Persoon { private String filmrol;

}

=> Schrijf gepaste toString() methode voor ‘betekenisvolle’ uitvoer

(7)

class Persoon {

private String naam;

private int geboortejaar;

public Persoon() { }

public Persoon(String naam, int geboortejaar) { this.naam = naam;

this.geboortejaar = geboortejaar;

} } class Acteur extends Persoon {

private String filmrol;

public Acteur() {

//automatische oproep van default constructor van basisklasse!!!

}

public Acteur(String naam, int geboortejaar, String filmrol) {

//automatische oproep van default constructor van basisklasse!!!

} }

Acteur angelina = new Acteur("Angelina Jolie", 1975, "Mr. & Mrs. Smith");

System.out.println(angelina);

Automatische oproep default constructor van basisklasse…

(8)

Acteur brad = new Acteur();

System.out.println(brad);

Acteur angelina = new Acteur("Angelina Jolie", 1975, "Mr. & Mrs. Smith");

System.out.println(angelina);

class Persoon {

private String naam;

private int geboortejaar;

public Persoon() { }

public Persoon(String naam, int geboortejaar) { this.naam = naam;

this.geboortejaar = geboortejaar;

} } class Acteur extends Persoon {

private String filmrol;

public Acteur() {

//automatische oproep van default constructor van basisklasse!!!

}

public Acteur(String naam, int geboortejaar, String filmrol) { super(naam, geboortejaar);

this.filmrol = filmrol;

} }

…tenzij expliciet anders vermeld!!

(9)

Acteur angelina = new Acteur("Angelina Jolie", 1975, "Mr. & Mrs. Smith");

Acteur brad = new Acteur();

null(0) speelt in null

Angelina Jolie(1975) speelt in Mr. & Mrs. Smith Uitvoer met gepaste toString() methode:

(Netbeans Variables venster) (IntelliJ Variables venster)

(10)

package presentatie;

import logica.Acteur;

public class Console {

public static void main(String[] args) { Acteur brad = new Acteur();

System.out.println(brad);

} }

package logica;

class Persoon {

private String naam;

private int geboortejaar;

}

VERKLARING: ‘default’ zichtbaarheid van een klasse is package toegang !!!

package logica;

class Acteur extends Persoon { private String filmrol;

}

Code georganiseerd in 2 packages – Probleem…

(11)

package presentatie;

import logica.Acteur;

public class Console {

public static void main(String[] args) { Acteur brad = new Acteur();

System.out.println(brad);

} }

package logica;

class Persoon {

private String naam;

private int geboortejaar;

}

OPLOSSING: Maak je logische klasse publiek toegankelijk !!!

package logica;

publicclass Acteur extends Persoon { private String filmrol;

}

Code georganiseerd in 2 packages - Oplossing

(12)

Voorbeeld – klasse Spin

(13)

Een overervende klasse in code (a)

public class Dier {

private int aantalPoten;

public void setAantalPoten(int aantalPoten) { this.aantalPoten = aantalPoten;

}

@Override

public String toString() {

return "Dier met " + this.aantalPoten + " poten";

} } public class Console {

public static void main(String[] args) { Spin s = new Spin();

s.setAantalPoten(8);

s.maakWeb();

System.out.println(s);

} }

spin maakt web

Dier met 8 poten public class Spin extends Dier { public void maakWeb() {

System.out.println("spin maakt web");

} } Compileert dit ?

Wat komt er op het scherm?

Relevante data van Spin object s:

(14)

Variant(b)

public class Console {

public static void main(String[] args) { Spin s = new Spin();

s.maakWeb();

System.out.println(s);

} }

public class Dier {

privateint aantalPoten;

public void setAantalPoten(int aantalPoten) { this.aantalPoten = aantalPoten;

}

@Override

public String toString() {

return "Dier met " + this.aantalPoten + " poten";

} }

public class Spin extends Dier { public Spin() {

//alle spinnen hebben 8 poten this.setAantalPoten(8);

}

public void maakWeb() {

System.out.println("spin maakt web");

} }

(15)

Variant(c)

Een standaard constructor roept normaal de standaard constructor van zijn basisklasse op….

tenzij je zelf via super(…) bepaalt dat een andere basisklasse constructor moet worden gebruikt.

public class Console {

public static void main(String[] args) { Spin s = new Spin();

s.maakWeb();

System.out.println(s);

} }

public class Dier {

private int aantalPoten;

public Dier(int aantal) {

this.aantalPoten = aantal;

}

@Override

public String toString() {

return "Dier met " + this.aantalPoten + " poten";

} }

public class Spin extends Dier { public Spin() {

super(8);

}

public void maakWeb() {

System.out.println("spin maakt web");

}

(16)

Voorbeeld - Winkelier

(17)

public class Persoon { private String naam;

private String voornaam;

public Persoon(String naam, String voornaam) { this.naam = naam;

this.voornaam = voornaam;

} }

public class Winkelier extends Persoon { }

public class Console {

public static void main(String[] args) { Winkelier w = new Winkelier();

} }

OPLOSSING:Naast niet-standaard constructor ook expliciet standaard constructor voorzien in basisklasse

Voorbeeld - Winkelier

Zoek de compilatiefout !

VERKLARING: De ‘gegenereerde’ standaard constructor roept standaard constructor op van basisklasse…

Maar in de klasse Persoon is er geen standaard constructor gedefinieerd of gegenereerd

(18)

public class Persoon { private String naam;

private String voornaam;

public void setNaam(String naam) { this.naam = naam;

}

public void setVoornaam(String voornaam) { this.voornaam = voornaam;

} }

public class Winkelier extends Persoon { }

Object wordt, na standaard initialisatie,

van data voorzien door oproep van gepaste setter methoden

Functioneel werkend geheel

public class Console {

public static void main(String[] args) { Winkelier w = new Winkelier();

w.setNaam("Maes");

w.setVoornaam("Evi");

} }

(19)

public class Persoon { private String naam;

private String voornaam;

public Persoon(String naam, String voornaam) { this.naam = naam;

this.voornaam = voornaam;

} }

public class Winkelier extends Persoon {

public Winkelier(String naam, String voornaam) { super(naam, voornaam);

} } public class Console {

public static void main(String[] args) {

Winkelier w = new Winkelier("Maes", "Evi");

Schoen s = new Schoen();

w.verkoop(s);

} }

Je object initialiseren via niet-standaard constructor

De betere implementatie ☺

(20)

public class Persoon { private String naam;

private String voornaam;

public Persoon(String naam, String voornaam) { this.naam = naam;

this.voornaam = voornaam;

} }

public class Schoen { }

public class Console {

public static void main(String[] args) {

Winkelier w = new Winkelier( "Maes", "Evi");

Schoen s = new Schoen();

w.verkoop(s);

} }

Winkelier@....verkoopt Schoen@...

Compileert dit ?

Wat komt er op het scherm?

public class Winkelier extends Persoon {

public Winkelier(String naam, String voornaam) { super(naam, voornaam);

}

public void verkoop(Schoen s) {

System.out.println(this + " verkoopt " + s);

} }

Extra

(21)

public class Persoon { private String naam;

private String voornaam;

public Persoon(String naam, String voornaam) { this.naam = naam;

this.voornaam = voornaam;

}

@Override

public String toString() {

return this.naam + " " + this.voornaam;

} }

public class Schoen {

@Override

public String toString() { return "een schoentje";

public class Console {

public static void main(String[] args) {

Winkelier w = new Winkelier( "Maes", "Evi");

Schoen s = new Schoen();

w.verkoop(s);

} }

Compileert dit ?

Wat komt er op het scherm?

public class Winkelier extends Persoon {

public Winkelier(String naam, String voornaam) { super(naam, voornaam);

}

public void verkoop(Schoen s) {

System.out.println(this + " verkoopt " + s);

Extra

Maes Evi verkoopt een schoentje

(22)

package test;

public class Console {

public static void main(String[] args) {

TvProgramma tvProg = new TvProgramma();

String s = tvProg.naam + " van " + tvProg.van + " tot " + tvProg.tot + " (" + tvProg.genre + ")";

for (int i = 0; i < tvProg.acteurs.length; i++) { s+= ("\n\t – " + tvProg.acteurs[i] );

}

System.out.println(s);

} }

package test;

class Programma { privateString naam;

protected LocalDate van, tot;

publicString genre;

}

package test;

class TvProgramma extends Programma { privateActeur[] acteurs;

}

Zoek de compilatiefouten !

2020 – Kristien Van Assche

Voorbeeld – TvProgramma (Met focus op zichtbaarheid van de velden)

(23)

package test;

public class Console {

public static void main(String[] args) {

TvProgramma tvProg = new TvProgramma();

String s = tvProg.naam+ " van " + tvProg.van+ " tot " + tvProg.tot + " (" + tvProg.genre + ")";

for (int i = 0; i < tvProg.acteurs.length; i++) { s+= ("\n\t – " + tvProg.acteurs[i] );

}

System.out.println(s);

} }

package test;

class Programma { privateString naam;

protected LocalDate van, tot;

publicString genre;

}

package test;

class TvProgramma extends Programma { privateActeur[] acteurs;

}

Sleutelwoorden private, protected & public

VERKLARING: sleutelwoord ‘protected’ geeft impliciet ‘package’ toegang !!!

(24)

package test;

public class Console {

public static void main(String[] args) {

TvProgramma tvProg = new TvProgramma();

System.out.println (tvProg);

} }

package test;

class Programma { privateString naam;

protectedLocalDate van, tot;

publicString genre;

}

package test;

class TvProgramma extends Programma { privateActeur[] acteurs;

@Override

public String toString() { String s = this.naam ;

s += " van " + this.van+ " tot " + this.tot ; s += " (" + this.genre + ")";

for (int i = 0; i < this.acteurs.length; i++) { s+= ("\n\t – " + this.acteurs[i] );

}

return s;

} }

2020 – Kristien Van Assche

Sleutelwoorden private, protected & public

(25)

package test;

public class Console {

public static void main(String[] args) {

TvProgramma tvProg = new TvProgramma();

System.out.println ( tvProg);

} }

package test;

class Programma { privateString naam;

protectedLocalDate van, tot;

publicString genre;

publicString getNaam() { return this.naam;

} package test; }

class TvProgramma extends Programma { privateActeur[] acteurs;

@Override

publicString toString() { String s = this.getNaam() ;

s += " van " + this.van + " tot " + this.tot; s += " (" + this.genre+ ")";

for (int i = 0; i < this.acteurs.length; i++) { s+= ("\n\t – " + this.acteurs[i] );

}

return s;

Sleutelwoorden private, protected & public

(26)

package test;

public class Console {

public static void main(String[] args) {

TvProgramma tvProg = new TvProgramma();

System.out.println ( tvProg);

} }

package test;

class Programma { privateString naam;

protectedLocalDate van, tot;

publicString genre;

@Override

public String toString() { String s = this.naam; s += " van " + this.van s += " tot " + this.tot ; s += " (" + this.genre + ")";

return s;

} } package test;

class TvProgramma extends Programma { privateActeur[] acteurs;

@Override

public String toString() { String s = super.toString();

for (Acteur a : acteurs) { s+= ("\n\t – " + a);

}

return s;

} }

2020 – Kristien Van Assche

De betere variant

(27)

Alle velden zijn null-referenties…

Debug-Demo!

(28)

Ook bij Exceptions automatische oproep van parent default constructor

28

Force step into

☺ Polymorfe

werking

(29)

class TvProgramma extends Programma { private Acteur[] acteurs;

public TvProgramma() {

this.acteurs = new Acteur[0];

}

public TvProgramma(String naam, String van, String tot, String genre, Acteur[] acteurs) {

super(naam, van, tot, genre);

this.acteurs = acteurs;

} }

Voorzie de gewenste constructoren van gepaste initialisatie

class Programma {

private String naam, genre;

private LocalDate van, tot;

public Programma() { this.naam = "";

this.van = LocalDate.of(1999,1,1);

this.tot = LocalDate.of(1999,1,1);

this.genre ="";

}

public Programma(String naam,

LocalDate van, LocalDate tot, String genre) {

this.naam = naam;

this.van = van;

this.tot = tot;

this.genre = genre;

} TvProgramma tvProg = new TvProgramma();

System.out.println (tvProg);

TvProgramma tvProg2 = new TvProgramma(…, …, …, …);

System.out.println (tvProg2);

(30)

• Afzonderlijke package voor Presentatie en Logica

=> public class Acteur

• Expliciete oproep toString methode van basisklasse:

=> super.toString()

• Initialiseer de niet-primitieve velden in constructoren!

• Impliciete oproep van default constructor van basisklasse, en dat doorheen ganse klassenhiërarchie

• Expliciete oproep niet-default constructor van basisklasse:

=> super(…, …);

• Steeds als eerste lijn in constructor!

• Meerdere overloads mogelijk

Besluiten

(31)

public class Persoon { private String naam;

private String voornaam;

public Persoon(String naam, String voornaam) { this.naam = naam;

this.voornaam = voornaam;

}

@Override

public String toString() {

return this.naam + " " + this.voornaam;

} }

public class Werknemer extends Persoon { private double loon;

public Werknemer(String naam, String voornaam, double loon) { super(naam, voornaam);

this.loon = loon;

}

@Override

public String toString() {

return super.toString() + ": " + this.loon + "€ brutoloon";

public class Console {

public static void main(String[] args) {

Werknemer[] personeel = new Werknemer[3];

personeel[0] = new Werknemer("Adriaanssens", "Adam", 1400.0);

personeel[1] = new Werknemer("Bastiaens", "Bea", 1500.0);

personeel[2] = new Werknemer("Claeys", "Chris", 1600.0);

for (Werknemer w : personeel) { System.out.println(w);

} } }

Voorbeeld – werknemers en hun loon

Compileert dit ?

Wat komt er op het scherm?

Adriaanssens Adam: 1400.0€ brutoloon Bastiaens Bea: 1500.0€ brutoloon

(32)

32 2020 – Kristien Van Assche

Arbeider

Werknemer

Bediende Persoon

Polymorfisme

- double loon - String naam - String voornaam

(33)

Arbeiders en bedienden

public class Arbeider extends Werknemer {

public Arbeider(String naam, String voornaam, double uurloon) { super(naam, voornaam, uurloon);

}

@Override

public String toString() {

return super.toString() + " per uur";

} }

public class Bediende extends Werknemer {

public Bediende(String naam, String voornaam, double maandloon) { super(naam, voornaam, maandloon);

}

@Override

public String toString() {

return super.toString() + " per maand";

}

(34)

public class Console {

public static void main(String[] args) {

Werknemer[] personeel = new Werknemer[3];

personeel[0] = new Arbeider("Adriaanssens", "Adam", 10.0);//upcast !!!

personeel[1] = new Bediende("Bastiaens", "Bea", 1500.0);//upcast !!!!

personeel[2] = new Bediende("Claeys", "Chris", 1600.0);//upcast !!!!

for (Werknemer w : personeel) { System.out.println(w);

} } }

Adriaanssens Adam: 10.0€ brutoloon per uur Bastiaens Bea: 1500.0€ brutoloon per maand Claeys Chris: 1600.0€ brutoloon per maand

Polymorfe werking

Compileert dit ?

Wat komt er op het scherm?

Arbeider

Werknemer

Bediende upcast

“POLY” (i.e. meerdere) + ”MORF” (i.e. gedaante) Wijzigende verschijningsvorm

(35)

Juiste condities voor polymorfe werking

public class Console {

public static void main(String[] args) {

Werknemer[] personeel = new Werknemer[3];

personeel[0] = new Arbeider("Adam", "Adriaanssens", 10.0); //upcast, cf. overerving !!!

personeel[1] = new Bediende("Bea", "Bastiaens", 1500.0); //upcast, cf. overerving !!!!

personeel[2] = new Bediende("Chris", "Claeys", 1600.0); //upcast, cf. overerving !!!!

for (Werknemer w : personeel)

System.out.println(w); // late binding, downcast, overriden toString implementatie }

} }

Condities tot polymorf gedrag zijn:

• Overerving

• Overriding

• Upcast/Downcast

• Late binding

Arbeider

Werknemer

Bediende downcast

(36)

public class Console {

public static void main(String[] args) { Gezin famStorms = new Gezin();

famStorms.addGezinslid(new Ouder("Stan", "Storms", Geslacht.MAN, LocalDate.of(1966, 12, 19))); //upcast famStorms.addGezinslid(new Ouder("Marie", "Maes", Geslacht.VROUW, LocalDate.of(1968, 4, 12))); //upcast

famStorms.addGezinslid(new Kind("Evi", "Storms", Geslacht.VROUW, LocalDate.of(2005, Month.MARCH, 8))); //…

famStorms.addGezinslid(new Kind("Nathan", "Storms", Geslacht.MAN, LocalDate.of(2010, Month.APRIL, 25))); //…

famStorms.addGezinslid(new Kind("Helen", "Storms", Geslacht.VROUW, LocalDate.of(2015, Month.JUNE, 15))); //…

System.out.println(famStorms); //late binding, downcast, overriden toString impl.

} }

Vader: Storms Stan (1966) Moeder: Maes Marie (1968) - Storms Evi (18 jaar)

- Storms Nathan (16 jaar) - Storms Helen (13 jaar)

- Ontwerp klassendiagramma

- Implementeer gevraagde functionaliteit Gewenste uitvoer:

Oefening

(37)

klassendiagramma

Referenties

GERELATEERDE DOCUMENTEN

Public-Private Partnerships cover a broad spectrum of arrangements under which partnerships between public and private sector organisations are developed for the purpose of

This research fills these research gaps by answering the research question: ‘How does the interplay between contractual and relational conditions in the internal

The allocation of operation risk to Railink has contributed to the achievement of first two objectives of the project: the expansion of railway service to

[r]

Dan zijn er niet alleen beter uitgewerkte procedures en contracten nodig, maar zullen er ook vaak nieuwe instanties in het leven moeten worden geroepen die beter zijn toegerust

The combinet (COMBINE Title) package, which should only be used in conjunc- tion with the combine class, modifies the \maketitle command of all imported documents so that the

The implementation of macros can be documented using this environment. The actual 〈macro code〉 must be placed in a macrocode environment. Longer macro definition can be split

The main determinants of the cost deviations reported in the literature are (i) imprecise project concept design planning, risk management and implementation, and poorly