Klasy i obiekty w Javie: konstruktor, static, rekordy
Zaktualizowano 22 października 2026
Klasy i obiekty w Javie rozwiązują problem, z którym pojedyncze zmienne i tablice sobie nie radzą: konto bankowe składa się z właściciela i salda, a do tego można na nie wpłacać pieniądze. Klasa łączy takie dane z pasującymi do nich metodami. Jest planem budowy, a za pomocą new tworzysz z niej dowolnie wiele obiektów.
Zwykle każda klasa stoi we własnym pliku nazwanym tak jak ona, np. Account.java. W przykładach tutaj wszystko jest w jednym pliku, żebyś widział to na pierwszy rzut oka. Wtedy tylko Main może być public.
Pola, konstruktor, metody
- Pola (atrybuty) to dane każdego obiektu. Są
private: dostęp do nich ma tylko sama klasa. Z zewnątrz odbywa się to przez metody takie jakgetBalance(), czyli gettery. Nazywa się to hermetyzacją (enkapsulacją). - Konstruktor nazywa się tak jak klasa, nie ma typu zwracanego i wykonuje się przy
new Account("Ada"). Wypełnia pola. this.ownerto pole obiektu, samoownerto parametr. Jeśli oba nazywają się tak samo, potrzebujeszthis.- Metody bez
staticpracują na polach obiektu, na którym je wywołujesz:ada.deposit(50)zmienia tylko konto Ady. toString()określa, jak obiekt wygląda jako tekst.println(ada)wywołuje tę metodę automatycznie.
final przed polem oznacza: jest ustawiane raz w konstruktorze i potem już nigdy się nie zmienia.
class Account { private final String owner; private double balance;
public Account(String owner) { this.owner = owner; this.balance = 0; }
public void deposit(double amount) { if (amount > 0) { balance += amount; } }
public double getBalance() { return balance; }
public String toString() { return owner + ": " + balance + " €"; }}
public class Main { public static void main(String[] args) { Account ada = new Account("Ada"); Account bob = new Account("Bob"); ada.deposit(50); ada.deposit(-10); bob.deposit(20); System.out.println(ada); System.out.println(bob); System.out.println("Ada has " + ada.getBalance()); }}static i stałe
Pole bez static istnieje raz w każdym obiekcie. Pole ze static istnieje tylko raz dla całej klasy i wszystkie obiekty je współdzielą. Możesz w ten sposób liczyć na przykład, ile obiektów już powstało. Metodę static wywołujesz przez nazwę klasy: Ticket.issued(). Nie ma ona this, dlatego nie może czytać zwykłych pól. Właśnie dlatego w prostych programach wszystko jest static: main działa, zanim powstanie jakikolwiek obiekt.
static final tworzy stałą, zapisywaną wielkimi literami: public static final int MAX = 7;.
Klasa może mieć kilka konstruktorów. Za pomocą this(...) w pierwszej linii jeden wywołuje drugi, dzięki czemu logika jest tylko w jednym miejscu:
public Duration(int minutes, int seconds) { this(minutes * 60 + seconds);}
class Ticket { public static final String OFFICE = "Town hall"; private static int counter = 0; private final int number;
public Ticket() { counter++; this.number = counter; }
public int getNumber() { return number; }
public static int issued() { return counter; }}
public class Main { public static void main(String[] args) { Ticket a = new Ticket(); Ticket b = new Ticket(); Ticket c = new Ticket(); System.out.println(Ticket.OFFICE); System.out.println("a: " + a.getNumber()); System.out.println("c: " + c.getNumber()); System.out.println("Issued: " + Ticket.issued()); }}Rekordy
Dla klas, które tylko trzymają razem dane, jest skrócona forma: record Point(int x, int y) { }. Ta jedna linia tworzy pola private final, konstruktor, gettery x() i y() (bez get), toString() w postaci Point[x=3, y=4] oraz equals, które porównuje wartości.
Rekord jest niezmienny. Jeśli coś ma się „zmienić”, metoda zwraca nowy rekord, tak jak moved w przykładzie. Math.abs(n) zwraca wartość bezwzględną liczby, czyli bez znaku.
record Point(int x, int y) { public int distance(Point p) { return Math.abs(x - p.x()) + Math.abs(y - p.y()); }
public Point moved(int dx, int dy) { return new Point(x + dx, y + dy); }}
public class Main { public static void main(String[] args) { Point a = new Point(3, 4); Point b = a.moved(1, -2); System.out.println(a); System.out.println(b); System.out.println("x of b: " + b.x()); System.out.println("Distance: " + a.distance(b)); System.out.println(a.equals(new Point(3, 4))); System.out.println(a == new Point(3, 4)); }}Typowe błędy
Przesłonięte pole
Jeśli parametr albo zmienna lokalna nazywa się tak samo jak pole, przesłania je. Obie linie wyglądają poprawnie, a pola nie zmieniają:
public Player(String name) { name = name; // parameter assigned to itself} public void addPoints(int points) { int score = this.score + points; // new local variable}Poprawnie jest
this.name = name;orazscore = score + points;bezint.Porównywanie obiektów przez ==
==sprawdza, czy to ten sam obiekt. Dwa punkty o tych samych wartościach to mimo to dwa obiekty, co pokazuje ostatnia linia przykładu z rekordem. Do porównywania wartości służyequals, w rekordach dostępne automatycznie.Zapomniane toString
Bez własnego
toString()wywołanieprintln(book)wypisuje coś w rodzajuBook@1b6d3586. Metoda musi nazywać się dokładniepublic String toString().Odczyt pola w metodzie static
W metodzie
staticnie ma obiektu, a więc nie ma teżthis. Jeśli odwołasz się tam do zwykłego pola, kompilator zgłosinon-static variable cannot be referenced from a static context.Puste miejsca w tablicy obiektów
new Measurement[7]tworzy siedem pustych miejsc, wszystkie równenull. Jeśli wywołasz na którymś metodę, program zakończy się błędemNullPointerException. Przechodź tylko po miejscach, które już wypełniłeś, albo od razu użyjArrayList(zobacz listy i mapy w Javie).
Zadania z tego tematu
Przećwicz to, czego się nauczyłeś, od razu w przeglądarce. Testy natychmiast sprawdzają twoje rozwiązanie.
Powiązane artykuły
- Dziedziczenie i interfejsyDziedziczenie w Javie w prosty sposób: extends, super, @Override, klasy abstrakcyjne, interfejsy i Comparable z przykładami. Do tego typowe błędy.Czytaj artykuł
- Metody i rekurencjaMetody w Javie w prosty sposób: parametry, return, przeciążanie, varargs i rekurencja z przykładami. Do tego typowe błędy, np. brakujący return.Czytaj artykuł
- Listy i mapyListy i mapy w Javie w prosty sposób: ArrayList, HashSet i HashMap z przykładami. Do tego typowe błędy, np. List<int> i remove na liczbach.Czytaj artykuł