Главная страница

АБОБА. Справочник по программированию на Java Методическое пособие


Скачать 242.41 Kb.
НазваниеСправочник по программированию на Java Методическое пособие
АнкорАБОБА
Дата20.02.2022
Размер242.41 Kb.
Формат файлаdocx
Имя файла12642_java_method_1.docx
ТипСправочник
#368066
страница45 из 67
1   ...   41   42   43   44   45   46   47   48   ...   67

Переменная суперкласса может ссылаться на объект подкласса


Ссылочной переменной суперкласса может быть присвоена ссылка на любой подкласс, производный от данного суперкласса. Этот аспект наследования будет весьма полезен во множестве ситуаций. Рассмотрим следующий пример:

class RefDemo {

public static void main(String args[]) {

BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);

Box plainbox = new Box();

double vol;

vol = weightbox.volume();

System.out.println("Объем weightbox равен " + vol);

System.out.println("Вес weightbox равен " +

weightbox.weight);

System.out.println();

// присваивание объекту BoxWeight ссылки на ссылку объекта Box

plainbox = weightbox;

vol = plainbox.volume(); // OK, метод volume() определен в Box

System.out.println("Объем plainbox равен " + vol);

BookNew_JAVA-7.indb 195 02.06.2007 1:06:53

196 Часть I. Язык Java

/* Следующий оператор ошибочен, поскольку plainbox

не определяет член weight. */

// System.out.println("Вес plainbox равен " + plainbox.weight);

}

}

В этом примере weightbox – ссылка на объекты BoxWeight, а painbox – ссылка на объекты Box. Поскольку BoxWeight – подкласс класса Box, ссылке painbox можно присваивать ссылку на объект weightbox.

Важно понимать, что доступные объекты определяются типом ссылочной переменной, а не типом объекта, на который она ссылается. То есть при присваивании ссылочной переменной суперкласса ссылки на объект подкласса доступ предоставляется только к указанным в ней частям объекта, определенного суперклассом. Именно поэтому объект plainbox не имеет доступа к переменной weight даже в том случае, когда он ссылается на объект BoxWeight. Если немного подумать, это становится понятным – суперклассу не известно, что именно подкласс добавляет в него. Поэтому последняя строка кода в предыдущем фрагменте оформлена в виде комментария. Ссылка объекта Box не имеет доступа к полю weight, поскольку оно не определено в классе Box.

Использование ключевого слова super


В предшествующих примерах классы, производные от класса Box, были реализованы не столь эффективно и надежно, как могли бы. Например, конструктор BoxWeight явно инициализирует поля width, height и depth класса Box. Это не только ведет к дублированию кода суперкласса, что весьма неэффективно, но и предполагает наличие у подкласса доступа к этим членам. Однако в ряде случаев придется создавать суперкласс, подробности реализации которого доступны только для него самого (т.е. с приватными членами данных). В этом случае подкласс никак не сможет самостоятельно непосредственно обращаться или инициализировать эти переменные. Поскольку инкапсуляция – один из главных атрибутов ООП, не удивительно, что Java предлагает решение этой проблемы.

Во всех случаях, когда подклассу нужно сослаться на его непосредственный суперкласс, это можно выполнить с помощью ключевого слова super.

Ключевое слово super имеет две общих формы. Первую используют для вызова конструктора суперкласса, а вторую – для обращения к члену суперкласса, скрытому членом подкласса. Рассмотрим обе формы.

Подкласс может вызывать конструктор, определенный его суперклассом, с помощью следующей формы ключевого слова super:

super(список_аргументов);

Список_аргументов определяет любые аргументы, требуемые конструктору в суперклассе. Оператор super() всегда должен быть первым выполняемым внутри конструктора подкласса.

В качестве иллюстрации использования оператора super() рассмотрим следующую усовершенствованную версию класса BoxWeight():

// Теперь класс BoxWeight использует ключевое слово super

// для инициализации своих атрибутов объекта Box.

class BoxWeight extends Box {

double weight; // вес параллелепипеда

// инициализация переменных width, height и depth с помощью super()

BoxWeight(double w, double h, double d, double m) {

super(w, h, d); // вызов конструктора суперкласса

weight = m;

}

}

В этом примере метод BoxWeight вызывает super() с аргументами w, h и d. Это приводит к вызову конструктора Box(), который инициализирует width, height и depth, используя переданные ему значения этих параметров. Теперь класс BoxWeight не инициализирует эти значения самостоятельно. Ему нужно инициализировать только свое уникальное значение – weight. В результате при необходимости эти значения могут оставаться приватными значениями класса Box.

В приведенном примере метод super() был вызван с тремя аргументами. Поскольку конструкторы могут быть перегруженными, super() можно вызывать, используя любую форму, определенную суперклассом. Программа выполнит тот конструктор, который соответствует указанным аргументам.

Рассмотрим основные концепции применения конструктора super(). Когда подкласс вызывает конструктор super(), он вызывает конструктор своего непосредственного суперкласса. Таким образом, super() всегда ссылается на суперкласс, расположенный в иерархии непосредственно над вызывающим классом. Это положение справедливо даже в случае многоуровневой иерархии. Кроме того, оператор super() всегда должен быть первым оператором, выполняемым внутри конструктора подкласса. Вторая форма ключевого слова super действует подобно ключевому слову this, за исключением того, что она всегда ссылается на суперкласс подкласса, в котором она использована.

Вторая форма применения ключевого слова super наиболее подходит в тех ситуациях, когда имена членов подкласса скрывают члены суперкласса с такими же именами.

Рассмотрим следующую простую иерархию классов:

// Использование ключевого слова super для предотвращения скрытия имени.

class A {

int i;

}

// Создание подкласса посредством расширения класса A.

class B extends A {

int i; // эта переменная 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 UseSuper {

public static void main(String args[]) {

B subOb = new B(1, 2);

subOb.show();

}

}

Эта программа отображает следующее:

i в суперклассе: 1

i в подклассе: 2

Хотя переменная экземпляра i в классе B скрывает переменную i в классе A, ключевое слово super позволяет получить доступ к переменной i, определенной в суперклассе. Как вы увидите, ключевое слово super можно использовать также для вызова методов, которые скрываются подклассом.
1   ...   41   42   43   44   45   46   47   48   ...   67


написать администратору сайта