Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Объектно-ориентированное программирование.PDF
Скачиваний:
208
Добавлен:
01.05.2014
Размер:
3.64 Mб
Скачать

converted to PDF by BoJIoc

непосредственно предшествующим родителем. То есть конструктор класса C может быть записан следующим образом:

C() : D(12), B(), A() { ... }

Конструкторы для виртуальных базовых классов должны вызываться первыми, то есть до конструкторов невиртуальных предков.

Виртуальные методы, определенные в виртуальных базовых классов, также могут быть источником проблем. Предположим, что каждый из четырех классов в листинге 13.5 обладает методом с именем initialize(). Он определен как виртуальный в классе Stream и переопределяется в каждом из последующих трех классов. Методы initialize() в классах

InStream и OutStream вызывают Stream::initialize() и, кроме того, выполняют некоторую специфическую для каждого из классов инициализацию.

Теперь рассмотрим метод initialize() для класса InOutStream. Он не может вызвать оба унаследованных метода InStream::initialize() и OutStream::initialize() без того, чтобы не вызвать дважды метод Stream::initialize(). Повторное обращение к методу Stream::initialize(), вероятно, будет иметь побочные эффекты. Способ из-бежать этой проблемы: переписать Stream::initialize() так, чтобы он определял, была ли уже осуществлена инициализация. Другой вариант: переопределить методы классов InStream и OutStream, чтобы они не вызывали метод класса Stream. В последнем случае класс InOutStream должен в явном виде обращаться к процедуре инициализации каждого из трех классов.

13.5. Множественное наследование в Java

Язык Java не поддерживает множественное наследование классов, но реализует множественное наследование интерфейсов. Класс может указать, что он поддерживает несколько различных интерфейсов. Например, один интерфейс может требовать запоминания данных на диске, а другой определять протокол самоотображения объектов. Запоминаемый графический объект будет поддерживать оба эти интерфейса:

class graphicalObject implements Storable, Graphical

{

// ...

}

В то время как классы не могут наследовать от двух и более классов (расширяя их), интерфейсам это разрешено. Мы имеем право определить интерфейс для запоминаемых графических объектов следующим образом:

interface GraphicalObject extends Storable, Graphical

{

// ...

}

Литература для дальнейшего чтения

Критика множественного наследования встречается у Саккинена [Sakkinen 1988a]. Упомянутая работа является сокращенной адаптированной версией его Ph. D. диссертации [Sakkinen 1992]. Объяснение множественного наследования в языке C++

дается Эллис [Ellis 1990].

Упражнения

1.Приведите два примера множественного наследования в ситуациях, не связанных с компьютерами.

2.В работе [Wiener 1989] описан «практический пример множественного наследования в C++». Определен класс IntegerArray, который наследует от двух