Metoda clone()
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 43 z 87.
Metoda clone() tworzy kopię obiektu. Aby jej użyć, Twoja klasa musi implementować interfejs Cloneable i nadpisać metodę clone() z klasy Object.
public class Person implements Cloneable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public Person clone() {
try {
return (Person) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}Teraz możesz tworzyć niezależne kopie obiektów:
Person original = new Person("Alice", 25);
Person copy = original.clone();
// copy jest osobnym obiektem o tych samych wartościachDomyślnie clone() wykonuje kopię płytką, co oznacza, że kopiuje wartości typów prostych i referencje. Jeśli Twój obiekt zawiera inne obiekty jako pola, zarówno oryginał, jak i kopia będą odwoływać się do tych samych zagnieżdżonych obiektów. Aby uzyskać naprawdę niezależne kopie z zagnieżdżonymi obiektami, musisz zaimplementować kopię głęboką, klonując również te zagnieżdżone obiekty w swojej metodzie clone().
Wyzwanie
ŁatwyStwórzmy system zarządzania dokumentami, który pokazuje klonowanie obiektów. Utworzysz klasę Document, którą można klonować, aby tworzyć niezależne kopie. Dzięki temu użytkownicy będą mogli duplikować dokumenty, nie zmieniając oryginału.
Umieścisz swój kod w dwóch plikach:
Document.java: Utwórz klasę reprezentującą dokument, która obsługuje klonowanie. Dokument ma trzy prywatne pola:title(String),author(String) iversion(int). Dodaj konstruktor inicjalizujący wszystkie pola oraz metody pobierające ich wartości. Dodaj też metodęsetVersion(int version), aby aktualizować numer wersji.Niech Twoja klasa Document implementuje interfejs
Cloneablei nadpisuje metodęclone(), aby zwracała obiekt typuDocument. Obsłuż wyjątekCloneNotSupportedExceptionwewnątrz metody, opakowując go wRuntimeException.Nadpisz
toString(), aby zwracała:Document[title=X, author=Y, version=Z], gdzie X, Y i Z to rzeczywiste wartości pól.Main.java: Ożyw swoją klasę Document, tworząc dokument i klonując go. Otrzymasz trzy dane wejściowe: tytuł (String), autora (String) i numer wersji (int).Utwórz oryginalny dokument z tymi wartościami, a następnie sklonuj go, aby utworzyć kopię. Po sklonowaniu zmodyfikuj wersję kopii, zwiększając ją o 1 za pomocą
setVersion(). W ten sposób pokażesz, że klon jest naprawdę niezależny od oryginału.Wypisz trzy wiersze:
Original:, a następnie wynik wywołania toString() dla oryginalnego dokumentuClone:, a następnie wynik wywołania toString() dla sklonowanego dokumentuIndependent:, a następnietruelubfalse, wskazujące, czy oryginał i klon są różnymi obiektami (użyj porównania!=)
Otrzymasz trzy dane wejściowe: tytuł dokumentu (String), nazwisko autora (String) i numer wersji (int).
Zauważ, że po zmodyfikowaniu wersji klonu oryginalny dokument pozostaje niezmieniony. Dowodzi to, że clone() utworzyła naprawdę niezależną kopię!
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 title = scanner.nextLine();
String author = scanner.nextLine();
int version = scanner.nextInt();
// TODO: Utwórz oryginalny obiekt Document z wartościami wejściowymi
// TODO: Sklonuj oryginalny dokument, aby utworzyć kopię
// TODO: Zmień wersję klonu, zwiększając ją o 1
// TODO: Wypisz "Original: ", a następnie oryginalny dokument
// TODO: Wypisz "Clone: ", a następnie sklonowany dokument
// TODO: Wypisz "Independent: ", a następnie true/false (sprawdź, czy original != clone)
}
}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