Наслідування та узагальнення. Посилальні типи та клонування об’єктів. Records
У Java успадкування, узагальнення, посилальні типи та клонування об’єктів, а також новий тип структур даних — `records` (доступні з Java 14) є важливими аспектами мови програмування, які забезпечують більшу гнучкість та можливості для написання більш ефективного і чіткого коду. Наслідування та узагальнення. Посилальні типи та клонування об’єктів. Records
1. Успадкування та узагальнення (Наслідування та узагальнення. Посилальні типи та клонування об’єктів. Records)
Успадкування з узагальненням
Класи з узагальненням можуть використовувати механізм успадкування, що дозволяє дочірнім класам успадковувати загальні властивості від батьківського класу.
Приклад узагальненого класу з успадкуванням:
public class Box<T> {
private T value;
public Box(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
// Успадкування з узагальненням
public class IntegerBox extends Box<Integer> {
public IntegerBox(Integer value) {
super(value);
}
}
public class Main {
public static void main(String[] args) {
IntegerBox intBox = new IntegerBox(100);
System.out.println(intBox.getValue()); // Виведе 100
}
}
Тут клас IntegerBox успадковує узагальнений клас Box з фіксованим типом Integer. Це дозволяє обмежити використання цього класу лише певним типом.
Успадкування в межах узагальнених класів:
Коли ви працюєте з успадкуванням і узагальненням, важливо розуміти, що параметри типів не успадковуються автоматично. Ви можете явно визначити параметри типів для кожного рівня ієрархії.
Приклад:
public class Parent<T> {
private T value;
public Parent(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
public class Child<U> extends Parent<U> {
public Child(U value) {
super(value);
}
}
public class Main {
public static void main(String[] args) {
Child<String> child = new Child<>(“Hello”);
System.out.println(child.getValue()); // Виведе “Hello”
}
}
Тут `Child<U>` наслідує `Parent<U>`, і тип `U` передається від батьківського класу до дочірнього.
2. Посилальні типи та клонування об’єктів
Посилальні типи
У Java посилальні типи вказують на об’єкт у пам’яті, а не на конкретне значення, як це роблять примітивні типи. Коли ви передаєте об’єкт у метод або присвоюєте його іншій змінній, ви передаєте посилання на цей об’єкт, а не його копію. Це означає, що зміни, внесені через одну змінну, будуть відображатися й через іншу.
Приклад:
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder(“Hello”);
changeString(sb);
System.out.println(sb); // Виведе “Hello, World!”
}
public static void changeString(StringBuilder str) {
str.append(“, World!”);
}
}
У цьому прикладі об’єкт `StringBuilder` передається за посиланням, і зміни в методі `changeString` відображаються в основному коді.
Клонування об’єктів
Клонування дозволяє створити копію об’єкта. Java надає метод `clone()`, який доступний у класі `Object`. Для використання цього методу клас повинен реалізовувати інтерфейс `Cloneable`, а сам метод має бути перевизначений для надання клонування.
Простий приклад клонування:
public class Person implements Cloneable {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public static void main(String[] args) {
try {
Person person1 = new Person(“John”);
Person person2 = (Person) person1.clone();
System.out.println(person1.getName()); // Виведе “John”
System.out.println(person2.getName()); // Виведе “John”
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
Метод `clone()` створює поверхневу копію об’єкта, тобто копіюється лише сам об’єкт, а не його вкладені об’єкти. Для глибокого клонування потрібно додатково реалізовувати клонування вкладених об’єктів.
3. Records (доступні з Java 14)
Records — це новий тип класів, який з’явився в Java 14 (в стабільному релізі з Java 16), і він призначений для створення незмінних класів (immutable classes). Вони забезпечують спрощений синтаксис для оголошення класів, які призначені лише для зберігання даних.
Ключові характеристики:
- record автоматично генерує конструктор, `equals()`, `hashCode()`, та `toString()` методи.
- Дані в record є незмінними (immutable).
Приклад використання record:
public record Person(String name, int age) {}
public class Main {
public static void main(String[] args) {
Person person = new Person(“John”, 30);
System.out.println(person.name()); // Виведе “John”
System.out.println(person.age()); // Виведе 30
}
}
У цьому прикладі `record` автоматично створює конструктор, геттери (методи `name()` і `age()`), а також реалізовує методи `equals()`, `hashCode()` і `toString()`.
Переваги використання record:
- Спрощений синтаксис: немає потреби вручну оголошувати всі поля, конструктори, геттери та методи для порівняння об’єктів.
- Чітка семантика: `record` забезпечує незмінність даних, що дозволяє уникнути випадкових змін стану об’єктів.
Особливості:
- Поля в record є незмінними. Вони можуть бути лише final.
- record не можна успадковувати або бути успадкованим, оскільки є обмеження на змінюваність (immutability).
Висновок Наслідування та узагальнення. Посилальні типи та клонування об’єктів. Records
- Успадкування та узагальнення дозволяють створювати більш гнучкі та багаторазові класи, що працюють із різними типами даних.
- Посилальні типи дають змогу передавати об’єкти за посиланням, а клонування дозволяє створювати копії об’єктів.
- Records — це нова зручна структура даних для зберігання незмінних об’єктів із мінімальним синтаксисом, що спрощує оголошення класів.
Наслідування та узагальненняПосилальні типи та клонування об’єктівRecords