Маркетинг

Больше данных – меньше проблем!


Новые системы хранения данных для компаний малого и среднего бизнеса. Узнайте подробности и задайте вопросы на on-line-семинаре IBM




Открытые системы :: Разработчику

О проблемах множественного наследования

в buzz в мой мир в twitter версия для печатисохранить в pdf

Множественное наследование, применяемое для описания объектов при объектно-ориентированном программировании, описывая в ряде случаев наблюдаемые связи между существующими реалиями, имеет проблемы технической реализации

Илья Труб

Множественное наследование, применяемое для описания объектов при объектно-ориентированном программировании, описывая в ряде случаев наблюдаемые связи между существующими реалиями, имеет проблемы технической реализации

Как известно, одним из главных преимуществ объектно-ориентированного программирования является наглядное представление свойств объектов окружающего мира и взаимосвязей между ними. О наиболее удачных примерах эффективного применения этого метода можно сказать: «Как видим, так и программируем». Концепции, позволяющие достичь этого, хорошо известны — инкапсуляция, наследование, полиморфизм. Естественным развитием второй концепции является множественное наследование, воплощенное, например, в языке программирования С++, когда объект некоторого класса наследует свойства объектов двух и более классов. Однако множественное наследование, описывая в ряде случаев наблюдаемые связи между существующими реалиями, имеет проблемы технической реализации.

Говоря о проблемах реализации, в первую очередь отмечают совпадение имен переменных и методов у предков класса и неоднозначности пути наследования в случае более чем двухуровневой иерархии. Для того чтобы разрешить эти проблемы, потребовалось ввести дополнительные конструкции, такие как виртуальные базовые классы и полные ссылки на методы. Применение этих конструкций усложняет код программы и снижает его наглядность. У концепции множественного наследования имеются и иные изъяны принципиального характера, не позволяющие имеющимися средствами описать те зависимости, с которыми мы сталкиваемся в реальной жизни. Возьмем в качестве примера шахматную фигуру — ферзя. Фраза «Ферзь ходит как слон и как ладья» полностью описывает его свойства: она абсолютно информативна. С точки зрения логики, это очень четкий, предельно концентрированный пример множественного наследования. Но можно ли «произнести» эту фразу в программе на С++ и ничего больше не добавлять? Иными словами, должен быть работоспособен следующий код, выдержанный в классических традициях объектно-ориентированного анализа (рис. 1) и языка С++. Для краткости опущены проверки принадлежности значений параметров конструктора и методов допустимому диапазону.

Рис. 1. Иерархия классов шахматных фигур
enum coord1 {a ,b ,c, d, e, f, g, h};
enum  color {Черный, Белый};
/* абстрактный класс Фигура — общий
 предок всех остальных */
class Фигура
{coord1 буква;	//1-я координата a..h
int цифра;	//2-я координата 1..8
color цвет;	//цвет фигуры
public:
//конструктор
Фигура(coord1 x, int y, color z)
{буква=x;
цифра=y;
цвет=z;
}
  /*чисто виртуальная функция «ход» —
 реализации в этом классе не имеет*/
  virtual int ход(coord1 новая_буква, 
int новая_цифра)=0;
}
/* Класс Ладья реализует 
 функцию «ход» */
class Ладья: public virtual Фигура {
public:
int ход(coord1 новая_буква, 
int новая_цифра) {
if (((новая_буква==буква)&& 
(новая_цифра!=цифра))||
((новая_буква!=буква) &&
(новая_цифра==цифра))) {
буква=новая_буква; 
цифра=новая_цифра; return 1;
}
  else return 0;
  }
/* Класс Слон реализует 
свою функцию ход */
class Слон: public virtual Фигура {
public:
int ход(coord1 новая_буква, 
int новая_цифра) {
if((abs((новая_буква-буква)==
abs (новая_цифра-цифра)) &&
(новая_буква!=буква)){
буква=новая_буква;
цифра=новая_цифра; return 1;
}
  else return 0;
}
/* Класс Ферзь — сказано лишь,
что он наследник классов
Ладья и Слон */
class Ферзь: public Слон, public Ладья{}
main(){
Ферзь q(e,5,Белый);
q.ход(h, 8);
}

Отметим, что свойство цвет в рассмотренном примере не существенно, и добавлено для общности и завершенности описания шахматной фигуры как объекта, стоящего на шахматной доске, а не лежащего в коробке. Так, для рассмотренных фигур реализация функции ход, конечно же, не зависит от цвета, так как они ходят и вперед, и назад, но, например, функция ход для класса Пешка уже должна будет располагать информацией о цвете для определения допустимости хода. Если же предположить существование на доске и других фигур, то для определения того, может ли одна фигура сбить другую, информация о цвете будет необходима уже для всех видов фигур.

Однако любой программист, имеющий опыт работы с языком С++, сразу же скажет, что такой код работать не будет более того, его не удастся даже откомпилировать из-за неоднозначности наследования функции ход. Одно из решений — функцию ход для класса Ферзь реализовать явно, например:

int Ферзь::ход(coord1 новая_буква, 
int новая_цифра){
    if (Ладья::ход(coord1 новая_буква, 
int новая_цифра)!=0) return 1;
    else if (Слон::ход(coord1 новая_буква, 
int новая_цифра)!=0) return 1;
    else return 0;
}

Однако в этом случае теряется смысл множественного наследования, ибо тогда зачем описывать класс Queen наследником слона и ладьи?

Таким образом, указанное отношение множественного наследования между объектами существующими средствами выразить нельзя. Для того чтобы устранить этот недостаток, можно предложить следующее расширение (или, как принято говорить, patch) для компилятора С++.

Пусть класс B является производным от классов A1, A2, ..., An. Пусть, кроме того, в каждом из родительских классов имеется реализация некоторого метода method, каждая из которых совпадает по количеству и типам входных параметров, а возвращает 0 или 1. Тогда, если в протоколе класса B отсутствует явная реализация метода method, по умолчанию она должна иметь следующий вид:

int B::method(<list of parameters>){
if (A1::method(<list of 
   parameters>)!=0) return 1;
else if (A2::method(<list of
   parameters>)!=0) return 1;
…
else if (An::method(<list of 
   parameters>)!=0) return 1;
else return 0;
}

При данном расширении рассмотренный программный код будет успешно компилироваться и работать.

Предложенное решение нельзя считать универсальным, поскольку оно реализует только одну комбинацию условий — дизъюнкцию. Вполне возможно, что имеются примеры объектных отношений, когда потребуется иная логическая функция. Кроме того, существенным ограничением является условие совпадения числа и типов параметров, а также интерпретация возвращаемого методом значения в виде «истина-ложь».

Укажем еще один аспект проблемы. Хотя описанный псевдокод действительно реализует дизъюнкцию, на самом деле он неявно предполагает совсем другую логическую функцию — «исключающее ИЛИ», когда из нескольких условий истинным должно быть не хотя бы одно из них, а ровно одно: только в этом случае выбор метода будет однозначен. Для шахматных фигур это естественно заложено в природе самих объектов, но теоретически возможна ситуация, когда условия применимости могут быть выполнены более чем для одной вариации метода, и тогда потребуется доопределить дополнительную функцию выбора. Это будет происходить в тех случаях, когда диапазоны значений параметров, задающих условия применимости для объектов базовых классов, имеют хотя бы одно непустое попарное пересечение, а параметры в вызове метода для объекта производного класса попадут именно в область этого пересечения. Впрочем, основываясь на практическом опыте, можно утверждать, что ситуация, которую покрывает предложенное правило, является наиболее распространенной.

Итак, концепция множественного наследования таит в себе немало «подводных камней», и ее полноценная реализация далеко не проста. В этой связи весьма показателен тот факт, что создатели языка Java, во многом базирующегося на С++, отказались от множественного наследования, заменив его менее рискованной реализацией абстрактных интерфейсов (implements) и разрешив обычное наследование (extends) только одного класса. Вообще говоря, практический опыт показывает, что задач, которые хорошо «ложатся» на объекты и для которых использование объектно-ориентированного программирования дает ощутимое преимущество, не так уж много. В большинстве приводимых в литературе примерах применение подобной методологии выглядит совершенно искусственным и ни в чем не убеждает.

Илья Труб (trub@surgu.wsnet.ru) — сотрудник Сургутского государственного университета.

15.02.2001г


Комментарии:


Для того, чтобы оставить комментарий авторизуйтесь или зарегистрируйтесь.

Новости ОСП-ТВ - 03.09.10


30/05/2007 №04

Миражи интеграции
Герман Хохлов
ИТ-рынок наконец-то осознал необходимость интеграции приложений — интеграционные платформы сегодня на пике популярности, а еще пару лет назад приходилось убеждать, что интегрировать лучше «на шине», чем с помощью прямых интерфейсов. Однако сегодня ожидания от внедрения интеграционных платформ часто значительно превосходят их реальные возможности. Мало того, встречаются даже случаи, когда шины рассматриваются как волшебные палочки, решающие все проблемы автоматизации и бизнеса. Интеграция приложений и интеграционные платформы постепенно становятся существенной статьей ИТ-бюджета.
Виртуализация: за и против
Александр Замятин
Сегодня технологии виртуализации вызывают большой интерес со стороны всех участников ИТ-рынка — все больше заказчиков видят в ИТ реальный инструмент бизнеса и все меньше внимания потребители информационных услуг уделяют оборудованию и программным средствам, на которых будет выполняться интересующая их задача. ИТ-инфраструктура все чаще оценивается как единое информационное поле, позволяющее получать, структурировать, обрабатывать и хранить необходимую компании информацию. Концепции виртуализации, начавшие развиваться около 40 лет назад, стали ответом на эти требования, однако виртуализация таит в себе не только преимущества.
Scrum: гибкое управление разработкой
Михаил Борисов
В большинстве случаев программирование — сложный, слабо определенный процесс, требующий от разработчиков творческого подхода. Различные agile-технологии позволяют организовать процесс постепенного приближения к цели проекта путем проведения циклов испытаний с корректировкой последующих, основанных на анализе результатов предыдущих. Scrum — одна из первых методологий циклического наращивания функциональности и корректировки хода проекта на основе анализа обратной связи от пользователей. Методология Scrum устанавливает правила управления процессом разработки и позволяет использовать уже существующие практики кодирования, корректируя требования или внося тактические изменения. Использование этой методологии дает возможность выявлять и устранять отклонения от желаемого результата на более ранних этапах разработки программного продукта.
Метрики управления качеством защиты приложений
Гуннар Петерсон, Элизабет Николс
Функциональность Web-приложений и их пользовательская база развиваются одновременно с ростом угроз, и хотя специальное оборудование (например, сетевые экраны) играет важную роль в деле защиты приложений, для обеспечения их полной безопасности одного оборудования недостаточно. Все эти устройства обеспечивают защиту хостов и средств связи, но почти бессильны перед атаками на сами программные модули или дизайн (интерфейсные экраны) приложения, поэтому предприятия должны сосредоточиться на усилении защиты Web-приложений. Однако здесь сразу появляется ряд вопросов. Какие проблемы могут возникнуть у моих программ? Насколько установленные приложения уязвимы перед лицом наиболее общих угроз? Какие изменения в цикле разработки программного обеспечения могут повлиять на защиту этих уязвимых мест?
Комбайн автоматизации
Александр Александров
Корпоративные платформы управления бизнес-процессами претендуют на то, чтобы, отделив логику выполнения процессов от их программной реализации, включить в единый цикл взаимодействие людей, потоки документов, распределенные информационные системы и базы данных. Когда появился такой «комбайн» с возможностью объединения анализа и моделирования процессов, управления действиями людей и работой информационных систем при обеспечении мониторинга и оптимизации производительности на протяжении жизненного цикла процессов, потребовалось переосмысление организации системы управления бизнес-процессами.
BPM со всех сторон
Наталья Дубова
Ежегодная конференция «Управление бизнес-процессами на предприятии: интеграция в корпоративные системы» вновь собрала полную аудиторию. С чем связан повышенный интерес к BPM и какие решения в данной области предлагаются сегодня отечественному бизнесу? Дисциплина управления бизнес-процессами сложилась в последнее десятилетие в ответ на неэффективную организацию бизнеса по функциональным подразделениям и избыточную сложность предлагаемых подходов к реинжинирингу бизнес-процессов, обычно предписывающих полную и одномоментную перестройку процессов из состояния «как есть» в состояние «как должно быть».
Транзакционная память — первые шаги
Леонид Черняк
Память современных компьютеров в принципе отличается от легендарных ферритовых колечек только своей емкостью и быстродействием: она последовательна по своей природе. С появлением многоядерных процессоров возникает необходимость в альтернативных решениях. Возможно, таким решением станет транзакционная память.

Содержание

Обучение

Разработчику

Книги

Системы управления базами данных

Советы и мнения

Современные архитектуры

Книжная полка ОС

Академия ОС

Стандарты

Программная инженерия

Приложения

Разное

Платформы

От редакции



Эта рубрика в архиве
Список номеров за



Инфозоны

DIRECTUM EVERYWHERE

УРАЛХИМ признал DIRECTUM

Система DIRECTUM стала корпоративным стандартом электронного документооборота в масштабах всего холдинга "Уралхим".

Уфа внедряет электронный муниципалитет

Платформа DIRECTUM стала центральным звеном в создаваемой информационной системе, направленной на повышение эффективности и открытости местных органов власти.

Цена вопроса

Кто и когда должен оценивать эффективность ECM-проектов? Как перейти от общих результатов к конкретным количественным характеристикам?

DIRECTUM во власти

Внедрение СЭД в Правительстве Астраханской области: система управления делами для 12 министерств и более 1300 сотрудников.
OSP.RU :: Написать письмо.