W poprzednich artykułach opisałem teorię i pokazałem przykłady kodu dotyczące tworzenia pierwszej klasy w języku Java, jak i gdzie zapisać wartości w klasie oraz jak wykonywać działania na klasie. Teraz przyszedł czas na ukrywanie, hermetyzowanie naszego kodu w klasie przed niepowołanym dostępem z innych fragmentów kodu.

Dlaczego mielibyśmy ukrywać nasz kod przed innymi klasami, developer’ami? W jaki sposób osiągnąć hermetyzację kodu? Dlaczego jest to tak ważne? Hermetyzacja jest jedną z trzech zasad programowania obiektowego, czyli: dziedziczenie, polimorfizm i hermetyzacja.

W języku Java hermetyzacja realizowana jest przez słowo kluczowe private, które może być używane dla klasy, metody oraz zmiennej.

// private - na poziomie klasy
private class Notebook {}

// private - na poziomie metody
private void goToPage(int page) {}

// private - na poziomie zmiennej
private int currentPage;

Dlaczego ukrywanie, hermetyzacja kodu przed innymi klasami jest taka ważna? Mając wiedzę z poprzednich artykułów wyobraźmy sobie klasę Thermostat, termostat umożliwia utrzymywanie zadanej temperatury, wprowadzana temperatura jest za pomocą klawiatury urządzenia (nie pokrętła). Termostat jest połączony z urządzeniem, które wydziela ciepło np. silnik samochodu i dba o prawidłową temperaturę pracy silnika. Jeżeli zmienna przechowująca ustawioną temperaturę nie miała by słowa kluczowego private, to można w dowolny sposób zmienić temperaturę i doprowadzić do uszkodzenia silnika.

Aby uniknąć wyżej opisanej sytuacji należy zmienne/pola/atrybuty klasy zrobić prywatnymi poprzez użycie słowa kluczowego private. Dodatkowo należy dodać warunek sprawdzający czy podana wartość temperatury dla termostatu mieści się w granicach poprawnej pracy urządzenia, np. 60 – 100 °C.

Poniżej przykład kodu ze zmienną prywatną.

public class Thermostat {
    private double temperature;
}

Poniżej próba użycia zmiennej temperature dla klasy Thermostat.

public class CarEngineMain {
    public static void main(String[] args) {
        Thermostat thermostat = new Thermostat();
//        thermostat.temperature = 99.99;
    }
}

Nie możemy skorzystać ze zmiennej temperature ponieważ jest ona prywatna i tylko metody w klasie Thermostat mogą z niej korzystać. Próba dostępu do zmiennej prywatnej kończy się błędem kompilacji, w tym przypadku otrzymujemy komunikat: ‘temperature’ has private access in ‘pl.juniorjavadeveloper.java.first.clazz.encatsulation.Thermostat’.

W takim razie co należy zrobić, aby zmienić wartość zmiennej prywatnej? Należy skorzystać z własnej metody publicznej, która ustawi wartość dla pola temperature w klasie Thermostat. Możemy zrobić, to na kilka sposobów, jednym z nich jest stworzenie dowolnej metody, która jako parametr będzie przyjmować zadaną temperaturę. Drugim sposobem jest skorzystanie z metod get/set, które są konwencją wykorzystywaną przez język Java.

Poniżej pierwszy sposób dostępu do zmiennych za pomocą własnej metody.

public class Thermostat {
    private double temperature;

    // metoda publiczna zmieniająca wartość temperatury termostatu
    public void changeTemp(double newTemperature) {
        this.temperature = newTemperature;
    }

    // metoda publiczna zwracająza wartość temperatury termostatu
    public double showTemp() {
        return this.temperature;
    }
}

Poniżej przykład użycia metod operujących na zmiennej temperature dla klasy Thermostat.

public class CarEngineMain {
    public static void main(String[] args) {
        Thermostat thermostat = new Thermostat();
//        thermostat.temperature = 99.99;

        thermostat.changeTemp(80.0);
        double showTemp = thermostat.showTemp();
        System.out.println("Temperatura dla termostatu: " + showTemp);
    }
}
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku - własne metody
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku – własne metody

Rozbudujemy powyższy kod z własnymi metodami o warunek sprawdzający poprawność ustawianej temperatury i sprawdzimy jego działanie. Metoda main() pozostaje bez zmian, wynik programu będzie przedstawiony na konsoli.

public void changeTemp(double newTemperature) {
    if (newTemperature >= 60 && newTemperature <= 100) {
        this.temperature = newTemperature;
    } else {
        System.out.println("Niepoprawna wartość temperatury!");
    }
}
    public static void main(String[] args) {
        Thermostat thermostat = new Thermostat();
//        thermostat.temperature = 99.99;

        thermostat.changeTemp(101.0);
        double showTemp = thermostat.showTemp();
        System.out.println("Temperatura dla termostatu: " + showTemp);
    }
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku – własne metody z warunkiem
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku – własne metody z warunkiem

Jak widać na powyższym zrzucie ekranu, temperatura termostatu nie została zmieniona, działa na ustawieniach początkowych.

Drugim sposobem na zmianę wartości dla zmiennych w klasie jest wykorzystanie metod get/set (getter/setter) zgodnie z konwencją nazewniczą języka Java. Co do zasady metody get/set nie powinny zawierać logiki np. warunków sprawdzających wartości zmiennych. O konwencji nazewniczej napiszę więcej za chwilę, na razie pokażę przykładowy kod oraz jak wygenerować getter/setter w IntelliJ IDEA używając skrótu ALT + Insert (kursor w dowolnym miejscu w klasie).

 public class Thermostat {
    private double temperature;

    public double getTemperature() {
        return temperature;
    }

    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }
}
Ukrywamy, hermetyzujemy nasz kod w klasie – get/set z ALT + Insert - wygenerowane getter/setter
« z 3 »

Na załączonych zrzutach ekranu widać jak łatwo wygenerować getter/setter, oczywiście trzeba znać konwencję do tworzenia tych metod. Najważniejsze, to wiedzieć po co w ogóle są te metody i do czego je używać. Metody te są zawsze publiczne, używany dla nich słowa kluczowego public.

Konwencja nazewnicza dla metody get/getter:
1. Metoda get/getter:
– bierzemy nazwę pola w klasie np. temperature,
– tworzymy publiczną, zwracającą ten sam typ, co zmienna,
– metoda musi mieć przedrostek get,
– do get dodajemy nazwę pola pisaną wielką literą, getTemperature,
– w metodzie zwracamy wartość pola w klasie.

public class Thermostat {
    private double temperature;

    public double getTemperature() {
        return temperature;
    }
}

Konwencja nazewnicza dla metody set/setter:
2. Metoda set/setter:
– bierzemy nazwę pola w klasie np. temperature,
– tworzymy publiczną metodę, która nic nie zwraca,
– metoda przyjmuje parametr tego samego typu, co zmienna,
– metoda musi mieć przedrostek set,
– do set dodajemy nazwę pola pisaną wielką literą, setTemperature,
– w metodzie ustawiamy wartość dla pola w klasie.

public class Thermostat {
    private double temperature;

    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }
}

Poniżej przykład użycia metod get/set.

public class CarEngineMain {
    public static void main(String[] args) {
        Thermostat thermostat = new Thermostat();

        thermostat.setTemperature(80.0);
        double temperature = thermostat.getTemperature();
        System.out.println("Temperatura dla termostatu: " + temperature);
    }
}
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku – metody get/set
Ukrywamy, hermetyzujemy nasz kod w klasie – kod Java, IntelliJ, krok po kroku – metody get/set

Podsumowując, hermetyzacja jest ważnym elementem programowania obiektowego. W języku Java hermetyzację kodu uzyskujemy za pomocą słowa kluczowego private. Dostęp do pól prywatnych realizowany jest za pomocą własnych metod i/lub metod get/set.

Całość kodu można znaleźć na:

Zapraszam do regularnego odwiedzania mojej strony, będą pojawiać się kolejne artykuły oraz do kontaktu przez email kontakt(at)juniorjavadeveloper.pl.