Programmeren in Java/Private en Public


Java werkt met zogenaamde access modifiers, die de zichtbaarheid van klassen, methoden, eigenschappen, etc. beïnvloeden. Met zichtbaarheid wordt er bedoeld in welke mate het mogelijk is om code te bereiken vanuit een ander stuk code die zich buiten de klasse bevindt. Tot nu toe hebben we enkel public gezien, public of publiek geeft, zoals de naam ook aangeeft, toegang tot code vanuit eender welke andere locatie in de Javacode.

In dit hoofdstuk gaan we dieper in op de access modifiers public en private.

PublicBewerken

public is het eerste sleutelwoord dat je wellicht bent tegen gekomen in Java, bijvoorbeeld in een simpel "Hello, world!" programma.

public class Main {

    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

public laat dus toe dat je de code vanuit eender waar kunt bereiken, dit is hier belangrijk aangezien public static void main het startpunt is van je programma. Moest je hier iets anders vermelden dan public, zou je het programma niet kunnen laten draaien aangezien de JVM geen startpunt kan vinden om te beginnen.

Je hebt ondertussen ook public gezien bij het aanmaken van klassen:

public class MyClass {

    public int number;

    public MyClass(int number) {
        this.number = number;
    }

    public void printNumber() {
        System.out.println(number);
    }

}

In dit voorbeeld, zie je dat public gebruikt werd bij het veld number, bij de constructor MyClass, de methode printNumber en ook bij de klasse zelf. Dat betekent dus dat alles van deze klasse toegankelijk is vanuit de rest van de code, bijvoorbeeld de main.

public class Main {

    public static void main(String[] args) {
        MyClass myClass = new MyClass(10);
        myClass.printNumber();
        myClass.number = 15;
        myClass.printNumber();
    }
}

Dit zal volgende output geven:

10
15

Aangezien dat het publiek is kun je altijd aan de code en dat kan misschien ongewenste gevolgen hebben. Stel dat je een klasse Person hebt die gegevens bijhoudt van een persoon, zoals bijvoorbeeld leeftijd. Je weet dat leeftijd nooit kleiner dan nul kan zijn, als je het veld voor leeftijd publiek maakt kan er van eender waar de leeftijd worden veranderd in het eender welke waarde, waaronder ook een foute leeftijd. Niets houdt iemand tegen om dan de leeftijd te veranderen naar bijvoorbeeld -9000. De access modifier private kan hierbij helpen.

PrivateBewerken

private sluit dus code af en maakt het enkel toegankelijk voor code binnen de klasse zelf. Om dit aan te tonen gaan we een klasse Person gebruiken.

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

Zoals je ziet heeft deze klasse de velden firstName, lastName en age die allemaal de access modifier private hebben gekregen. Dit betekent dus dat deze velden enkel binnen dezelfde klasse zichtbaar zijn. Om dit aan te tonen zullen we proberen om de leeftijd te veranderen in een main.

public class Main {

    public static void main(String[] args) {
        Person person = new Person("Klaas", "Janssen", 32);
        person.age = 20;
    }
}

Als je een goeie IDE gebruikt, zal je wellicht al meteen een foutmelding krijgen. Gebruik je geen IDE of geeft hij geen foutmelding zal je volgend foutbericht of iets gelijkaardigs krijgen als je probeert te compileren.

Main.java:5: error: age has private access in Person
        person.age = 20;
              ^
1 error

Je kunt ook het veld age niet uitlezen en bijvoorbeeld uitprinten met System.out.println. private betekent nu eenmaal dat het helemaal niet beschikbaar is buiten de klasse, want het is privé. Nu willen we nog steeds de leeftijd kunnen veranderen of tenminste uitlezen, dit kunnen we doen door een extra methodes in de klasse toe te voegen die wel public zijn zoals onderstaande.

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

getAge zal ons de waarde teruggeven van het veld age en setAge zal de waarde van het veld age veranderen naar de waarde die we meegegeven als argument. Zulke methodes worden getters en setters genoemd. getters voor informatie op te halen en setters om informatie in te stellen. Nu kunnen we deze methodes gebruiken in onze main.

public class Main {

    public static void main(String[] args) {
        Person person = new Person("Klaas", "Janssen", 32);
        System.out.println("Leeftijd: " + person.getAge());
        person.setAge(-12);
        System.out.println("Leeftijd: " + person.getAge());
    }
}

Dit zal ons volgende output gegeven.

Leeftijd: 32
Leeftijd: -12

Nu zie je dat we nog steeds foute informatie kunnen doorgeven via een setter, een persoon kan natuurlijk geen negatieve leeftijd hebben. Dit kun je makkelijk opvangen in de setter door wat code toe te voegen, bijvoorbeeld als volgt:

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0) {
            this.age = 0;
        } else {
            this.age = age;
        }
    }
}

In de setter hebben we nu een if/else statement geplaatst dat ervoor zorgt dat als je een negatief getal ingeeft de leeftijd op nul wordt gezet. Als je de main nog eens zou draaien krijgen je volgende output.

Leeftijd: 32
Leeftijd: 0

Je hoeft natuurlijk niet de leeftijd op nul zetten, je kunt de if gebruiken om bijvoorbeeld een IllegalArgumentException te gooien. Deze moet natuurlijk dan wel worden opgevangen op de plaats waar de methode setAge wordt gebruikt.

public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 0) {
            throw new IllegalArgumentException("Leeftijd kan niet kleiner zijn dan nul.");
        } else {
            this.age = age;
        }
    }
}

Andere access modifiersBewerken

Naast private en public heb je ook nog de volgende:

  • protected, geeft aan dat iets beschikbaar is zolang de code die het aanroept aan één van de volgende voorwaardes voldoet:
    • Binnen dezelfde klasse
    • Binnen dezelfde package
    • Of in een subklasse is van de klasse waar de code zich bevindt.
  • default, of ook soms package private genoemd, heeft ongeveer dezelfde regels als protected maar met het verschil dat als de code wordt opgeroepen van een subklasse dat die zich in dezelfde package bevindt. Ook wordt er in het geval van deze optie geen sleutelwoord gebruikt.

Deze komen later nog aan bod.

Informatie afkomstig van http://nl.wikibooks.org Wikibooks NL.
Wikibooks NL is onderdeel van de wikimediafoundation.