Słowo kluczowe final
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 13 z 87.
Słowo kluczowe final w Javie zapobiega modyfikacjom. Można je stosować do zmiennych, metod i klas, a za każdym razem wywołuje inny efekt.
Zastosowane do zmiennej, final sprawia, że staje się ona stałą — po przypisaniu jej wartość nie może się zmienić:
public class Circle {
private final double PI = 3.14159;
private final double radius;
public Circle(double radius) {
this.radius = radius; // Można przypisać wartość raz w konstruktorze
}
public void setRadius(double r) {
// this.radius = r; // Błąd! Nie można ponownie przypisać wartości do zmiennej final
}
}Zmienna final musi zostać zainicjalizowana podczas deklaracji lub w konstruktorze. Każda późniejsza próba przypisania jej nowej wartości powoduje błąd kompilacji.
W przypadku typów referencyjnych final oznacza, że referencja nie może wskazywać na inny obiekt, ale zawartość obiektu nadal może się zmieniać:
private final StringBuilder name = new StringBuilder("John");
// name = new StringBuilder("Jane"); // Błąd! Nie można przypisać ponownie
name.append(" Doe"); // OK! Zawartość obiektu może się zmieniaćUżycie final w polach jasno komunikuje intencję — informuje innych programistów, że ta wartość nie powinna się zmieniać po inicjalizacji. Jest to szczególnie przydatne w przypadku wartości konfiguracyjnych, identyfikatorów lub wszelkich danych, które muszą pozostać niezmienne przez cały czas istnienia obiektu.
Wyzwanie
ŁatwyZbudujmy system rejestracji Student, który używa słowa kluczowego final, aby chronić dane, które nie powinny się zmieniać po zarejestrowaniu studenta.
Utworzysz dwa pliki, aby uporządkować swój kod:
Student.java: Utwórz klasę Student, w której niektóre informacje zostaną trwale zablokowane po ich ustawieniu:- Pole
finalstudentId(String) — przypisywane podczas tworzenia i nie mogące się już zmienić - Pole
finalenrollmentYear(int) — rok zapisania się studenta, również niezmienny - Zwykłe pole prywatne
name(String) — można je zaktualizować, jeśli student zmieni nazwisko - Konstruktor, który przyjmuje wszystkie trzy wartości i inicjalizuje pola
- Getter
getStudentId()zwracający identyfikator studenta - Getter
getEnrollmentYear()zwracający rok zapisania się - Getter
getName()i settersetName()dla imienia i nazwiska - Metoda
getInfo(), która zwraca:"ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
- Pole
Main.java: Utwórz obiekt Student, następnie zaktualizuj jego imię i nazwisko oraz wyświetl jego informacje. Otrzymasz cztery dane wejściowe: identyfikator studenta, początkowe imię i nazwisko, rok zapisania się oraz nowe imię i nazwisko do ustawienia. Wypisz dwa wiersze:- Informacje o studencie przed zmianą imienia i nazwiska
- Informacje o studencie po zmianie imienia i nazwiska
Otrzymasz kolejno cztery dane wejściowe: studentId (String), name (String), enrollmentYear (int) oraz newName (String).
Zwróć uwagę, jak pola final chronią identyfikator studenta i rok zapisania się — są to trwałe dane, które nie powinny się zmieniać, podczas gdy imię i nazwisko można zaktualizować za pomocą settera.
Spróbuj swoich sił
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Wczytaj dane wejściowe
String studentId = scanner.nextLine();
String name = scanner.nextLine();
int enrollmentYear = scanner.nextInt();
scanner.nextLine(); // pomiń znak nowej linii
String newName = scanner.nextLine();
// TODO: Utwórz obiekt Student z wartościami początkowymi
// TODO: Wyświetl informacje o studencie przed zmianą imienia
// TODO: Zaktualizuj imię studenta za pomocą settera
// TODO: Wyświetl informacje o studencie po zmianie imienia
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online