Object georienteerd programmeren |
Object georienteerd is een oplossingsmethode, waarbij in de
analyse en ontwerpfase het probleem in objecten wordt verdeeld.
Een "object" is in gewoon Nederlands een
"ding". En een ding heeft eigenschappen, zoals kleur,
gewicht, lengte, snelheid, naam, enz. En het ding heeft een
gedrag, zoals rollen, rijden, werken, enz.
In object georienteerd talen waar Java er één van is worden
objecten rechtstreeks in de taal beschreven in een klasse.
Een klasse bestaat dan uit
| eigenschappen | data | field | veld |
| gedrag | functionaliteit | method | methode |
class Punt {
int x;
int y;
}
Een klasse heeft een naam in dit geval Punt. De Java naamconventie geeft aan dat een klassenaam met een hoofdletter begint. De leden (eng members) van de klasse staan tussen accolade. De klasse Punt heeft twee velden x en y.
Als een klasse wordt gedeclareerd wordt het een object of
instantie (eng. instantiation).
In Java wordt een nieuw object op de heap - een stuk dynamisch
geheugen - gealloceerd met de operator new. Het is object is
daarna te benaderen via de object referentie die door new wordt
teruggegeven.
Punt p; // de object referentie p = new Punt(); // alloceren van het object op de heap
Het kan ook in één keer:
Punt p = new Punt();
Nadat het object is gecreeerd met new behoeft het na zijn werkzame leven niet door de programmeur te worden verwijderd van de heap. Een object wordt automatisch van de heap verwijderd door de garbage collector :
De garbage collector is een onderdeel van de Virtual Machine en loopt in een eigen Thread parallel aan het Java programma. De garbage collector loopt op de laagste proiriteit om de performance van het lopende programma niet nadelig te beïnvloeden. Mocht het nodig zijn een groot object direct van de heap te verwijderen dan kan de garbage collector rechtstreeks aangeroepen worden met System.gc().
Velden zijn besproken bij hoofdstuk 2. Methode zijn reeds besproken in hoofdstuk 5. In Java zijn methode en velden altijd onderdeel van een klasse. Losstaande velden en methoden bestaan niet. Dit in tegenstelling tot de hybride taal als C++, die zowel functioneel als object georienteerd is.
Een veld binnen een klasse is te benaderen door:
p.x = 3; // geeft variabele x van de Punt p de waarde 3
Voor de methode clear als onderdeel van de Punt klasse geldt:
void clear() {
x = y = 0;
}
Een methode wordt aangeroepen via de object referentie en een punt.
Punt p = new Punt(); p.clear();
De this referentie wijst naar het eigen object. In principe kan iedere member van een object via de this referentie worden benaderd. Maar het hoeft niet
void clear() {
this.x = this.y = 0;
}
Soms is het echter noodzakelijk
void setX( int x) {
this.x = x;
}
De x is het argumentvariabele van de methode en this.x is het veld van de Punt klasse
Eén van de krachtigste eigenschappen van object georienteerd programmeren is de mogelijkheid om een klasse uit te breiden. We hoeven dan niet de programmacode van de oorspronkelijke klasse over te schrijven. De nieuwe klasse wordt afgeleid vn de oorspronkelijke klasse en daarmee bezit hij alle members van de oorspronkelijke..
class Pixel extends Punt {}
Met alleen deze zinsnede heeft de Pixel klasse de beschikking over de velden x en y en de methoden clear en setX gekregen.
class Pixel extends Punt { Color kleur;void clear() { // super.clear() is overschreven super.clear(); kleur = null; } }
De methode van de oorspronkelijke klasse, ook wel basisklasse of super klasse genoemd, kan worden bereikt met de super referentie. Zoals this de referentie naar deze klasse is super de referentie naar de bovenliggende basisklasse
Een nieuw gecreeerde klasse krijgt een beginstand door de velden een waarde te geven bij het declareren. Soms is dit echter niet toereikend en moet een initialisatie methode gebruikt worden. Voor dit soort gevallen zijn er constructors. Constructor hebben dezelfde naam als de klasse waartoe zij behoren. Ze kunnen net als alle methode overladen worden door andere parameters te gebruiken
class Punt { int x, y;Punt () { x = y = 0; }Punt (int x, int y) { this.x = x; this.y = y; } }
Deze constructor wordt aangeroepen bij de volgende zinsnede:
Punt a = new Punt(); // aanroep constructor zonder argumenten Punt a = new Punt(1,2); // aanroep constructor met twee argumenten
Van een klasse kan de innerlijke structuur worden gescheiden van het uiterlijk door de toegangsoperatoren: public, protected, private en package De toegangsoperator komt voor de memberfunctie of datamember te staan, waarvoor deze toegangscontrole geldt.
class X {
private int x;
public X() {
x = 3;
}
public int getX() {
return x;
}
public void setX(int a) {
x = a;
}
}
|
class Z {
X refX;
public Z() {
refX = new Ene();
}
void eenMethode)() {
refX.x = 3; // mag niet x is private
refX.setX(3) ; // mag wel getX is public
}
}
|
class Y extends X {
private int y = 5;
void printXenY() {
// mag NIET omdat x PRIVATE is
System.out.println( "x = " + x + " y = " + y);
}
}
|
class X {
protected int x;
public X() {
x = 3;
}
}
|
class Y extends X {
private int y = 5;
void printXenY() {
// mag WEL omdat x PROTECTED is
System.out.println( "x = " + x + " y = " + y);
}
}
|
Bij object georiënteerd ontwerpen is het een goed gebruik de datamembers van een object te verbergen. Andere delen van het programma kunnen dan de gegevens niet rechtstreeks benaderen, maar alleen indirect bijvoorbeeld via memberfuncties die wel public zijn. In Java is het mogelijk de toegang tot de leden (members) van een klasse te beperken.
Hiermee kan de programmeur de innerlijke structuur en werking verbergen voor de gebruiker. De redenen kunnen zijn,