Назад Зміст Вперед

7.2. Ключове слово super

Ключове слово super

У Java існує ключове слово super, яке позначає суперклас, тобто клас, похідним від якого є поточний клас. Подивимося, навіщо це потрібно.

У конструкторі HeavyBox ми дублювали поля width, height і depth, які вже є в класі Box.
class HeavyBox extends Box {
    int weight; // вага коробки
        // конструктор
    HeavyBox(int w, int h, int d, int m) {
        width = w;
        height = h;
        depth = d;
        weight = m; // маса
    }
}

Це не надто ефективно. Крім того, можливі ситуації, коли суперклас має закриті члени даних, але ми хочемо мати до них доступ. Через успадкування це не вийде, так як закриті члени класу доступні тільки рідному класу. У таких випадках ви можете послатися на суперклас.

Ключове слово super можна використовувати для виклику конструктора суперкласу і для звернення до члену суперкласу, захованого членом підкласу.

Використання ключового слова super для виклику конструктора суперкласу.

class HeavyBox extends Box {
    int weight; // вага коробки
        // конструктор
    // ініціалізація змінних за допомогою ключового слова super
    HeavyBox(int w, int h, int d, int m) {
        super(w, h, d); // виклик конструктора суперкласу
        weight = m; // маса
    }
}
Виклик методу super () завжди повинен бути першим оператором, виконуваним всередині конструктора підкласу.
При виклику методу super () з потрібними аргументами, ми фактично викликаємо конструктор Box, який ініціалізує змінні width, height і depth, використовуючи передані йому значення відповідних параметрів. Вам залишається ініціалізувати тільки своє доданий значення weight. При необхідності ви можете зробити тепер змінні класу Box закритими. Проставте для полів класу Box модифікатор private і переконайтеся, що ви можете звертатися до них без проблем.
У суперкласу може бути декілька перевантажених версій конструкторів, тому можна викликати метод super () з різними параметрами. Програма виконає той конструктор, який відповідає зазначеним аргументам.
Друга форма ключового слова super діє подібно ключовому слову this, тільки при цьому ми завжди посилаємося на суперклас підкласу, в якому вона використана. Загальна форма має наступний вигляд:
super.член
Тут член може бути методом або змінною екземпляра.

Подібна форма підходить в тих випадках, коли імена членів підкласу приховують члени суперкласу з такими ж іменами.

class A {
    int i;
}

// наслідник класу A
class B extends A {
    int i; // ім'я змінної співпадає і перекриває змінну i в класі A
    
    B(int a, int b) {
        super.i = a; // звертаємося до змінної i із класу A
        i = b; // звертаємося до змінної i із класу B
    }
    
    void show() {
        System.out.println("i із суперкласу: " + super.i);
        System.out.println("i в подкласі: " + i);
    }
}

class MainActivity {
    B subClass = new B(1, 2);
    subClass.show();
}
У результаті ми повинні побачити:
i із суперкласу: 1
i в піодкласф: 2

Таким чином, вираз super.onCreate (savedInstanceState) звертається до методу onCreate () з базового класу.

Приклад з трьох класів. Суперклас Box, підклас HeavyBox і підклас MoneyBox. Останній клас успадковує всі характеристики класів Box і HeavyBox, а також додає поле cost, яке містить вартість коробки.
Box.java
package ru.alexanderklimov.quickcourse;
class Box {
 private int width; // ширина коробки
 private int height; // висота коробки
 private int depth; // глибина коробки

 // Конструктор для створення клону об'єкта 
 Box(Box ob) { // передача об'єкта конструктору
  width = ob.width;
  height = ob.height;
  depth = ob.depth;
 }

 // Конструктор, який використовується при використанні всіх змінних
  Box(int w, int h, int d) {
  width = w;
  height = h;
  depth = d;
 }

 // Конструктор, коли ні одна із змінних не вказана
 Box() {
  // значення -1 використовується
  // для неініціалізованого паралелепіпеда
  width = -1;
  height = -1;
  depth = -1;
 }

 // Конструктор для створення куба
 Box(int len) {
  width = height = depth = len;
 }

 // обчислюємо об'єм коробки
 int getVolume() {
  return width * height * depth;
 }
}

HeavyBox.java

package ru.alexanderklimov.quickcourse;
//Додаємо вагу
class HeavyBox extends Box {
 int weight; // вага коробки

 // Конструктор клону об'єкта
 HeavyBox(HeavyBox ob) { // передача об'єкта конструктору
  super(ob);
  weight = ob.weight;
 }

 // Конструктор(вказані всі параметри)
 HeavyBox(int w, int h, int d, int m) {
  super(w, h, d); // виклик конструктора суперкласу
  weight = m; // вага
 }

 // Конструктор за замовчуванням
 HeavyBox() {
  super();
  weight = -1;
 }

 // Конструктор для створення куба
 HeavyBox(int len, int m) {
  super(len);
  weight = m;
 }
}

MoneyBox

package ru.alexanderklimov.quickcourse;
//Ціна коробки
class MoneyBox extends HeavyBox {
 int cost;

 // Конструктор клону об'єкта 
 MoneyBox(MoneyBox ob) { // передача об'єкта конструктору
  super(ob);
  cost = ob.cost;
 }

 // Конструктор(вказані всі параметри)
MoneyBox(int w, int h, int d, int m, int c) { super(w, h, d, m); // виклик конструктора суперкласу cost = c; } // Конструктор за замовчуванням MoneyBox() { super(); cost = -1; } // Конструктор для створення куба MoneyBox(int len, int m, int c) { super(len, m); cost = c; } }
К
У результаті ми отримаємо різні значення, обчислювані в коді. Завдяки спадкоємства, клас MoneyBox може використовувати класи Box і HeavyBox, додаючи тільки ту інформацію, яка нам потрібна для його власного спеціалізованого застосування. У цьому і полягає принцип успадкування, дозволяючи повторно використовувати код.
Метод super () завжди посилається на конструктор найближчого суперкласу в ієрархії. Тобто метод super () в класі MoneyBox викликає конструктор класу HeavyBox, а метод super () в класі HeavyBox викликає конструктор класу Box.
Якщо в ієрархії класів конструктор суперкласу вимагає передачі йому параметрів, всі підкласи повинні передавати ці параметри по естафеті.
В ієрархії класів конструктори викликаються в порядку спадкування, починаючи з суперкласу і закінчуючи підкласом. Якщо метод super () не застосовується, програма використовує конструктор кожного суперкласу, заданий за замовчуванням або не містить параметрів.
Ви можете створити три класи A, B, C, які успадковуються один від одного (A ← B ← C), у яких в конструкторі виводиться текст і викликати в основному класі код:
C c = new C();
Ви повинні побачити три рядки тексту, певні в кожному конструкторі класу. Оскільки суперклас нічого не знає про свої підкласи, будь-яка ініціалізація повністю незалежна і, можливо, обов'язкова для виконання будь-якою ініціалізацією, виконуваною підкласом.
Шилдт ст. 215
.