In deze blog zal ik verder in gaan op wat de code die je ziet staan in een Java klasse precies betekent en op hoe een klasse is opgebouwd. In het stukje over hoe je een Java klasse schrijft kwam het voorbeeld van de klasse Dobbelsteen al voorbij. Dit voorbeeld zal hier weer worden gebruikt. Op de onderstaande afbeelding is hij nogmaals te vinden.
Wat opvalt aan de code van de klasse Dobbelsteen is dat er in bijna ieder onderdeel public of private staat. Wat betekent dit nou precies? De sleutelwoorden public en private zijn toegangsspecificaties, of niveau's van toegankelijkheid, en bepalen waar de desbetreffende onderdelen zichtbaar en toegankelijk zijn. Java heeft vier verschillende toegangsspecificaties:
0 - private: het attribuut of de methode is alleen toegankelijk vanuit programmacode die tot dezelfde klasse behoort.
0 - package/geen specificatie: het attribuut of de methode is toegankelijk vanuit programmacode die behoort tot een klassendefinitie binnen dezelfde package. Er wordt geen sleutelwoord gebruikt, maar dit niveau wordt package genoemd.
0 - protected: een attribuut of methode met deze toegangsspecificatie is toegankelijk voor alle code uit dezelfde package en voor alle subklassen van de klasse. Het maakt dan niet uit in welke package deze subklassen zich bevinden, als de package maar toegankelijk is.
0 - public: een attribuut of methode met de toegangsspecificatie public is altijd toegankelijk.
Als je zelf een klasse schrijft, krijgen de attributen - met uizondering van constanten - de toegangsspecificatie private. Methoden krijgen over het algemeen de specificatie public. In de bovenstaande code van de klasse Dobbelsteen zie je een private attribuut ogen staan, een public constructor om Dobbelsteen objecten mee te maken, en twee public methoden, getOgen en werp.
De definitie van een klasse
De syntaxis van de bovenstaande code kan als volgt worden opgeschreven:
[packagedeclaratie]
[importopdrachten]
[commentaar]
toegang class klassennaam [extends klassennaam] {
[attribuutdeclaraties]
[constructordefinities]
[methodedefinities]
}
Deze volgorde is niet verplicht in Java (de delen tussen vierkante haken kunnen zelfs helemaal weggelaten worden), maar naast correcte code schrijven, wil je ook zorgen dat je code leesbaar is en overzichtelijk blijft voor wanneer het later - door jezelf of een andere programmeur - aangepast moet worden. Het is daarom handig om vrij consistent te zijn in de manier waarop je een klasse schrijft.
De syntaxis is opgebouwd uit verschillende elementen, zoals je in het stukje code kunt zien. Er zijn drie categorieën elementen:
0 - basissymbolen zoals Java-sleutelwoorden, haakjes, puntkomma's, etc,
0 - elementair syntactische begrippen, zoals 'klassennaam' die zelf niet verder uit gewerkt worden.
0 - syntactische begrippen die zelf ook in een regel gedefinieerd worden.
Hier volgen kort de vorm waarin de verschillende elementen uit de bovenstaande klassendefinitie geschreven moeten worden:
De packagedeclaratie: package packagenaam; (let op de ; op het einde!)
Voorbeeld: package dobbelsteen;
De importopdracht: import packagenaam.naam; (hier wordt één klasse geïmporteerd) of import packagenaam.*; (hier worden alle public klassen uit die package geïmporteerd.
Voorbeeld: import java.util.Random;
De signatuur: de onderdelen 'toegang class klassennaam' vormen de signatuur. Zoals je hierboven al hebt kunnen lezen zijn er vier toegangsniveau's in Java. De toegangsspecificatie van een klasse mag niet private zijn. Het sleutelwoord class moet er gewoon instaan en de klassennaam bedenk jezelf. Het is handig om een klasse niet x of y te noemen, maar een betekenisvolle naam te geven, zoals Dobbelsteen voor een klasse die een dobbelsteen werpt. Let er op dat volgens de Java conventies de klassennaam met een hoofdletter wordt geschreven.
Wanneer de klasse een subklasse is van een andere klasse komt het stukje 'extends klassennaam' er nog bij in de code. De klassennaam is in dat stukje de naam van de klasse waar de subklasse van erft.
Voorbeeld: public class Dobbelsteen {
De attribuutdeclaraties: attributen zijn variabelen, gedeclareerd binnen een klasse, en dus niet binnen een methode. Hun waarden definiëren samen de toestand van een bepaalde instantie van die klasse. De syntaxis is als volgt: toegang [static] [final] variabelendeclaratie; (de sleutelwoorden zijn optioneel). De syntax van de variabelendeclaratie is: type naam = expressie;
Wanneer static in de declaratie voorkomt betekent het dat het gaat om een klassenattribuut, en wanneer dit sleutelwoord ontbreekt betreft het een objectattribuut. Door het sleutelwoord final wordt aangegeven of een variabele een constante is. Dit zijn attributen waar slechts één keer een waarde aan wordt meegegeven, die daarna niet meer gewijzigd kan worden.
Het is niet verplicht om attributen een initiële waarde mee te geven, omdat dan gewoon de standaardwaarden worden toegekend. Door het wel te doen verhoog je de leesbaarheid van je code.
Voorbeeld: private int ogen = 0;
De constructordefinities: constructors worden gebruikt om attributen bij de creatie van een object een beginwaarde te geven die specifiek is voor dat object. Een constructor heeft altijd dezelfde naam als de klasse waarin deze is gedefinieerd. De syntaxis van een constructor ziet er als volgt uit:
[commentaar]
toegang naam (formeleparameterlijst)
blok
Voorbeeld:
/*
* Maakt een nieuwe Dobbelsteen instantie en genereert en bewaart
* een waarde tussen 1 en 6.
*/
public Dobbelsteen() {
this.werp();
}
De methodendefinities: in de methodendefinities schrijf je de code voor de methoden die de klasse kan gebruiken. De syntaxis van een methodefinitie ziet er als volgt uit:
[commentaar]
toegang [static] terugkeertype naam (formeleparameterlijst)
blok
Het blok bestaat uit een reeks opdrachten die samen de implementatie van de methode vormen. Een opdracht kan bijvoorbeeld een declaratie van een lokale variabele zijn, of een toekenning waarmee er een waarde wordt toegekend aan een variabele. Methoden die een terugkeertype hebben die niet void zijn, hebben een terugkeerwaarde. Deze methoden moeten in hun implementatie altijd minstens één return opdracht hebben. In die opdracht wordt de terugkeerwaarde vastgelegd.
Voorbeeld:
/*
* Genereert en bewaart een waarde tussen 1 en 6.
*/
public void werp(){
Random r = new Random();
ogen = r.nextInt(6) + 1;
}
Als je zelf een klasse schrijft, krijgen de attributen - met uizondering van constanten - de toegangsspecificatie private. Methoden krijgen over het algemeen de specificatie public. In de bovenstaande code van de klasse Dobbelsteen zie je een private attribuut ogen staan, een public constructor om Dobbelsteen objecten mee te maken, en twee public methoden, getOgen en werp.
De definitie van een klasse
De syntaxis van de bovenstaande code kan als volgt worden opgeschreven:
[packagedeclaratie]
[importopdrachten]
[commentaar]
toegang class klassennaam [extends klassennaam] {
[attribuutdeclaraties]
[constructordefinities]
[methodedefinities]
}
Deze volgorde is niet verplicht in Java (de delen tussen vierkante haken kunnen zelfs helemaal weggelaten worden), maar naast correcte code schrijven, wil je ook zorgen dat je code leesbaar is en overzichtelijk blijft voor wanneer het later - door jezelf of een andere programmeur - aangepast moet worden. Het is daarom handig om vrij consistent te zijn in de manier waarop je een klasse schrijft.
De syntaxis is opgebouwd uit verschillende elementen, zoals je in het stukje code kunt zien. Er zijn drie categorieën elementen:
0 - basissymbolen zoals Java-sleutelwoorden, haakjes, puntkomma's, etc,
0 - elementair syntactische begrippen, zoals 'klassennaam' die zelf niet verder uit gewerkt worden.
0 - syntactische begrippen die zelf ook in een regel gedefinieerd worden.
Hier volgen kort de vorm waarin de verschillende elementen uit de bovenstaande klassendefinitie geschreven moeten worden:
De packagedeclaratie: package packagenaam; (let op de ; op het einde!)
Voorbeeld: package dobbelsteen;
De importopdracht: import packagenaam.naam; (hier wordt één klasse geïmporteerd) of import packagenaam.*; (hier worden alle public klassen uit die package geïmporteerd.
Voorbeeld: import java.util.Random;
De signatuur: de onderdelen 'toegang class klassennaam' vormen de signatuur. Zoals je hierboven al hebt kunnen lezen zijn er vier toegangsniveau's in Java. De toegangsspecificatie van een klasse mag niet private zijn. Het sleutelwoord class moet er gewoon instaan en de klassennaam bedenk jezelf. Het is handig om een klasse niet x of y te noemen, maar een betekenisvolle naam te geven, zoals Dobbelsteen voor een klasse die een dobbelsteen werpt. Let er op dat volgens de Java conventies de klassennaam met een hoofdletter wordt geschreven.
Wanneer de klasse een subklasse is van een andere klasse komt het stukje 'extends klassennaam' er nog bij in de code. De klassennaam is in dat stukje de naam van de klasse waar de subklasse van erft.
Voorbeeld: public class Dobbelsteen {
De attribuutdeclaraties: attributen zijn variabelen, gedeclareerd binnen een klasse, en dus niet binnen een methode. Hun waarden definiëren samen de toestand van een bepaalde instantie van die klasse. De syntaxis is als volgt: toegang [static] [final] variabelendeclaratie; (de sleutelwoorden zijn optioneel). De syntax van de variabelendeclaratie is: type naam = expressie;
Wanneer static in de declaratie voorkomt betekent het dat het gaat om een klassenattribuut, en wanneer dit sleutelwoord ontbreekt betreft het een objectattribuut. Door het sleutelwoord final wordt aangegeven of een variabele een constante is. Dit zijn attributen waar slechts één keer een waarde aan wordt meegegeven, die daarna niet meer gewijzigd kan worden.
Het is niet verplicht om attributen een initiële waarde mee te geven, omdat dan gewoon de standaardwaarden worden toegekend. Door het wel te doen verhoog je de leesbaarheid van je code.
Voorbeeld: private int ogen = 0;
De constructordefinities: constructors worden gebruikt om attributen bij de creatie van een object een beginwaarde te geven die specifiek is voor dat object. Een constructor heeft altijd dezelfde naam als de klasse waarin deze is gedefinieerd. De syntaxis van een constructor ziet er als volgt uit:
[commentaar]
toegang naam (formeleparameterlijst)
blok
Voorbeeld:
/*
* Maakt een nieuwe Dobbelsteen instantie en genereert en bewaart
* een waarde tussen 1 en 6.
*/
public Dobbelsteen() {
this.werp();
}
De methodendefinities: in de methodendefinities schrijf je de code voor de methoden die de klasse kan gebruiken. De syntaxis van een methodefinitie ziet er als volgt uit:
[commentaar]
toegang [static] terugkeertype naam (formeleparameterlijst)
blok
Het blok bestaat uit een reeks opdrachten die samen de implementatie van de methode vormen. Een opdracht kan bijvoorbeeld een declaratie van een lokale variabele zijn, of een toekenning waarmee er een waarde wordt toegekend aan een variabele. Methoden die een terugkeertype hebben die niet void zijn, hebben een terugkeerwaarde. Deze methoden moeten in hun implementatie altijd minstens één return opdracht hebben. In die opdracht wordt de terugkeerwaarde vastgelegd.
Voorbeeld:
/*
* Genereert en bewaart een waarde tussen 1 en 6.
*/
public void werp(){
Random r = new Random();
ogen = r.nextInt(6) + 1;
}


Reacties
Een reactie posten