Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Пара слов о множественном наследовании, абстрактных типах данных и языке Java
Многие программисты знают, что в основу языка Java положен C++. Также известно, что создатели языка Java удалили из него возможность множественного наследования потому, что, по их мнению, это средство слишком усложняет программный код и идет в разрез с концепцией упрощения программных кодов, положенной в основу Java. С точки зрения создателей Java, 90% всех возможностей, предоставляемых множественным наследованием, можно получить с помощью интерфейса. Интерфейс в терминологии Java представляет собой нечто подобное абстрактному типу данных, в том смысле, что в нем также определяются функции, которые могут быть реализованы только в производных классах. Но новые классы не производятся непосредственно от интерфейса. Классы производят от других классов и в них передаются функции интерфейса, что напоминает множественное наследование. Так, союз абстрактных классов и множественного наследования породил на свет аналог классов- мандатов, в результате чего удалось избежать чрезмерного усложнения программных кодов, как в случае с множественным наследованием. Кроме того, поскольку интерфейсы не содержат ни выполняемых функций, ни переменных-членов, отпадает необходимость в виртуальном наследовании. Насколько удобны или целесообразны эти изменения, зависит от привычек конкретного программиста. Во всяком случае, если вы хорошо разберетесь в множественном наследовании и абстрактных типах данных языка C++, то это послужит хорошей базой при изучении и освоении последних достижений и тенденций программирования, реализованных в языке Java (если у вас возникнет интерес к нему). Использование логических конструкций в языках C++ и Java подробно рассматривается в следующей статье: Robert Martin, C++ and Java: А Critical Comparison // C++ Report. — January, 1997.
Резюме
Сегодня вы познакомились с методами преодоления некоторых ограничений одиночного наследования. Вы узнали об опасности передачи вверх по иерархии классов интерфейса производных функций и об ограничениях приведения типа данных объектов базового класса к производным классам во время выполнения программы. Кроме того, вы узнали, когда и как используется множественное наследование классов, какие проблемы при этом могут возникнуть и как их преодолеть. На этом занятии также было представлено объявление абстрактных типов данных и способы создания абстрактного класса с помощью чистых виртуальных функций. Особое внимание уделялось логике использования абстрактных данных для моделирования реальных ситуаций.
Вопросы и ответы
Что означает передача функциональности вверх по иерархии классов? Речь идет о переносе описаний общих функций-членов в базовые классы более высокого уровня. Если одна и та же функция используется в производных классах, имеет смысл описать эту функцию в общем для них базовом классе. Во всех ли случаях передача функциональности вверх целесообразна в программе? Если передаются вверх по иерархии только функции общего использования, то это целесообразно, но смысл теряется, если в базовые классы передается специфичный интерфейс производных классов. Другими словами, если метод не может быть использован во всех производных классах, то нет смысла описывать его в базовом классе. В противном случае вам во время выполнения программы придется отслеживать тип текущего объекта, прежде чем вызвать функцию. В чем проблема с контролем типа объекта при выполнении программы? В больших программах для выполнения контроля за типом объекта придется использовать достаточно массивный и сложный программный блок. Идея использования виртуальных функций состоит в том, что тип объекта определяется программой автоматически с помощью виртуальной таблицы, вместо того чтобы использовать для этого специальные программные блоки. Что плохого в приведении типа объектов? Приведение типов объектов к определенному типу данных, используемому конкретной функцией, довольно часто и эффективно используется в программах на C++. Но если программист применяет приведение типов для того, чтобы обойти заложенный в C++ строгий контроль за соответствием типов данных, например в случае приведения типа указателя к установленному во время выполнения программы типу объекта, то это говорит о серьезных недостатках в структуре программы, противоречащих идеологии C++. Почему бы не сделать все функции виртуальными? Для поддержания работы виртуальных функций создается виртуальная таблица, что увеличивает потребление памяти программой и время выполнения программы. Если в программе используется небольшой класс, от которого не производятся подклассы, то в использовании виртуальных функций нет никакого смысла. В каких случаях используются виртуальные деструкторы? Виртуальные деструкторы следует описывать в том случае, если в программе планируется использование указателя базового класса для получения доступа к объектам подклассов. Существует одно простое правило: если в программе описываются виртуальные функции, то обязательно должны использоваться виртуальные деструкторы. Для чего возиться с созданием абстрактных типов данных? Не проще ли создать обычный базовый класс, для которого просто не создавать объектов в программе? При написании программы всегда следует использовать такие подходы, которые гарантировали бы обнаружение ошибок в программе не во время ее выполнения, а во время компиляции. Если класс явно будет описан как абстрактный, то любая попытка создать объект этого класса приведет к показу компилятором сообщения об ошибке.
|