Klasa to plan
Do tej pory twój kod żył w metodach, które przekazują sobie zwykłe wartości. Klasa pozwala połączyć powiązane dane i działające na nich zachowanie w jeden nazwany typ. Klasa jest planem, a rzeczy, z którymi faktycznie pracujesz, to utworzone z niej obiekty.
Klasa deklaruje dwa rodzaje składowych: pola (dane, które przechowuje każdy obiekt) i metody (to, co każdy obiekt potrafi zrobić).
new Dog() buduje obiekt w pamięci i zwraca referencję do niego. d.name i d.bark() sięgają do tego konkretnego obiektu.
Każdy obiekt ma własny stan
Cały sens klasy polega na tym, że możesz utworzyć wiele niezależnych obiektów, z których każdy ma własne wartości pól. Zmiana jednego nigdy nie dotyka innego.
rex i bella to dwa osobne obiekty. Każdy ma własne name, więc każde bark() wypisuje inną wartość. Takie dane należące do konkretnego obiektu to stan instancji.
Pola i metody działają razem
Metody w klasie mogą bezpośrednio odczytywać i zmieniać pola swojego obiektu, bez przekazywania ich jako parametrów. Metoda już „żyje” w obiekcie, którego dane zmienia.
Zauważ, że increment() nie przyjmuje argumentów. Działa na polu tego obiektu Counter, na którym ją wywołano. To właśnie różni metodę klasy od swobodnej metody statycznej: metoda ma niejawny obiekt, na którym działa.
Słowo kluczowe this
Wewnątrz metody this to referencja do obiektu, na którym wywołano metodę. Zwykle go nie potrzebujesz: napisanie count już oznacza this.count. this staje się jednak niezbędne, gdy nazwa parametru koliduje z nazwą pola, co zdarza się ciągle w setterach i konstruktorach.
Częsty błąd początkujących to napisanie x = x; w move. To po prostu przypisuje parametr samemu sobie i nie zmienia pola. Kompilator nie ostrzeże, a obiekt po cichu zachowa stare wartości. Pole faktycznie aktualizuje dopiero this.x = x;.
Domyślne wartości pól i referencje null
Gdy tworzysz obiekt, jego pola nie zawierają śmieci: Java ustawia im wartości domyślne, czyli 0 dla liczb, false dla boolean i null dla referencji do obiektów, takich jak String. Ta domyślna wartość null to źródło klasycznej awarii.
u.name to null, bo nikt go nie ustawił, więc wywołanie na nim .length() rzuca NullPointerException. Zawsze przypisuj sensowne wartości, zanim użyjesz pól obiektu. Właśnie ten problem rozwiązują konstruktory.
Organizowanie kodu wokół klas
Prawdziwe programy modelują swoją dziedzinę jako klasy, które trzymają razem dane i operacje na nich. Tutaj jedna klasa BankAccount przechowuje saldo i pilnuje, jak się ono zmienia:
Dane (balance) i zasady ich zmiany (deposit, withdraw) są w jednym miejscu. Kod w innych miejscach prosi konto o wykonanie operacji, zamiast bezpośrednio zmieniać jego liczby. To podstawa czystego projektu, który łatwo utrzymać.
Dalej: konstruktory
Ustawianie każdego pola ręcznie po new jest żmudne i łatwo o nim zapomnieć, a jak widać, zapomniane pole zostawia null, który czeka, by wywołać awarię. Konstruktor pozwala wymagać i inicjalizować pola obiektu w chwili jego utworzenia, dzięki czemu BankAccount nigdy nie istnieje bez właściciela. To temat następnej strony.
Najczęściej zadawane pytania
Czym jest klasa w Javie?
Klasa to plan, który określa dane (pola) i zachowanie (metody), jakie będzie miał dany rodzaj obiektu. Sama klasa jest tylko szablonem: prawdziwe obiekty tworzysz z niej przez new. Na przykład klasa Dog opisuje, że każdy pies ma name i potrafi bark(), a każde new Dog() to osobny pies z własnym imieniem.
Czym różni się klasa od obiektu w Javie?
Klasa to definicja, a obiekt to konkretna instancja zbudowana z tej definicji przez new. Jedna klasa Person może dać wiele obiektów Person, z których każdy ma własne wartości pól. Pomyśl o klasie jak o foremce do ciastek, a o obiektach jak o pojedynczych ciastkach: zmiana pól jednego obiektu nigdy nie wpływa na inny.
Do czego służy słowo kluczowe this w klasie Javy?
this oznacza bieżący obiekt, czyli konkretną instancję, której metoda właśnie działa. Używasz go, aby dostać się do własnych pól obiektu, zwłaszcza gdy parametr ma taką samą nazwę jak pole (this.name = name;). Bez this przypisanie ustawiłoby parametr na samego siebie, a pole pozostałoby bez zmian.