Главная » Просмотр файлов » М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)

М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781), страница 43

Файл №1160781 М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (М. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000)) 43 страницаМ. Бен-Ари - Языки программирования. Практический сравнительный анализ (2000) (1160781) страница 432019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 43)

procedure Main is

S1.S2, S3: Set;

Ada

begin

S1 := Union(S2, S3);

end Main;

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

with Set_Package;

package Linked_Set_Package is

type Set is new Set_Package.Set with private;

function Union(S1, S2: Set) return Set;

Ada

function lntersection(S1, S2: Set) return Set;

private

type Node;

type Pointer is access Node;

type Set is new Set_Package.Set with

record

Head: Pointer;

end record;

end Linked_Set_Package;

Новая реализация может использоваться другим модулем; фактически, вы можете изменить реализацию, используемую в существующих модулях, про­сто заменяя контекстные указания:

Ada with Linked_Set_Package; use Linked_Set_Package;

Ada

procedure Main is

S1.S2, S3: Set;

begin

S1 := Union(S2, S3);

end Main;

В C++ абстрактный класс создается с помощью объявления чистой виртуаль­ной функции, обозначенной «начальным значением» 0 для функции.

Абстрактный класс для множеств в языке C++ выглядит следующим обра­зом:

class Set {

C++

public:

virtual void Union(Set&, Set&) = 0;

virtual void lntersection(Set&, Set&) = 0;

};

У абстрактных классов не бывает экземпляров; абстрактный класс может только быть базовым для производных классов:

class Bit_Set: public Set {

public:

virtual void Union(Set&, Set&);

virtual void lntersection(Set&, Set&);

C++

private:

int data[100];

};

class Linked_Set: public Set {

public:

virtual void Union(Set&, Set&);

virtual void lntersection(Set&, Set&);

private:

int data;

Set *next;

};

Конкретные производные классы можно использовать как любой другой класс: __

void proc()

{

C++

Bit_Setb1,b2, bЗ;

Linked_Set 11,12,l3;

b1.Union(b2,b3);

H.Union(l2,I3);

}

Обратите внимание на разницу в синтаксисе двух языков, которая вызвана разными подходами к ООП. В языке Ada 95 определяется обычная функция, которая получает два множества и возвращает третье. В языке C++ одно из множеств — отличимый получатель сообщения. Для

b1.Union(b2,b3);

подразумевается, что экземпляр b1, отличимый получатель операции Union, получит результат операции от двух параметров — Ь2 и bЗ — и использует его, • чтобы заменить текущее значение внутренних данных.

Возможно, вы предпочтете перегрузить предопределенные операции, например «+» и «*», вместо того чтобы использовать имена Union и Intersection. Это можно сделать как в C++, так и в Ada 95.

Все реализации абстрактного класса покрываются типом класса (CW-типом) Set'Class. Величины абстрактного CW-типа будут диспетчеризованы к правильному конкретному типу, т. е. к правильной реализации. Таким обра­зом, абстрактные типы и операции дают возможность программисту писать программное обеспечение, не зависящее от реализации.

Родовые возможности

В разделе 10.3 мы обсуждали родовые подпрограммы в языке Ada, которые позволяют программисту создавать шаблоны подпрограмм и затем конкретизировать их для различных типов. Родовые возможности чаще всего находят приложение в пакетах Ada; например, пакет работы со списком может быть родовым в отношении типа элементов списка. Кроме того, он может быть родовым в отношении функций, сравнивающих элементы, с тем

чтобы элементы списка можно было сортировать:

generic

type Item is private;

with function "<"(X, Y: in Item) return Boolean;

Ada

package List_Package is

type List is private;

procedure Put(l: in Item; L: in out List);

procedure Get(l: out Item; L: in out List);

private

type List is array( 1.. 100) of Item;

end List_Package;

Этот пакет теперь может быть конкретизирован для любого типа элемента:

Ada

package Integer_list is new List_Package(lnteger, Integer."<");

Конкретизация создает новый тип, и можно объявлять и использовать объекты этого типа:

lnt_List_1, lnt_List_2: lnteger_List.List;

lnteger_List.Put(42, lnt_List_1 );

lnteger_List.Put(59, lnt_List_2);

В языке Ada есть богатый набор нотаций для написания родовых формаль­ных параметров, которые используются в модели контракта, чтобы ограни­чить фактические параметры некоторыми классами типов, такими как диск­ретные типы или типы с плавающей точкой. В языке Ada 95 эти средства обобщены до возможности специфицировать в родовом формальном пара­метре классы типов, задаваемые программистом:

with Set_Package;

Ada

generic

type Set_Class is new Set_Package.Set; package Set_IO is

end Set_IO;

Эта спецификация означает, что родовой пакет может быть конкретизирован с любым типом, производным от тегового типа Set, такого как Bit_Set и Linked_Set. Все операции из Set, такие как Union, могут использоваться внут­ри родового пакета, потому что из модели контракта мы знаем, что любая конкретизация будет с типом, производным от Set, и, следовательно, она на­следует или замещает эти операции.

Шаблоны

В языке C++ можно определять шаблоны классов:

Ada

template <class ltem>

class List {

void put(const Item &);

};

Как только шаблон класса определен, вы можете определять объекты этого класса, задавая параметр шаблона:

C++

List<int>lnt_List1;

// lnt_List1 является экземпляром класса List с параметром int

Так же как и язык Ada, C++ позволяет программисту для объектов-экземп­ляров класса задать свои программы (процесс называется специализацией, spe­cialization) или воспользоваться по умолчанию подпрограммами, которые су­ществуют для класса. Есть важное различие родовых пакетов Ada и шаблонов C++. В языке Ada конкретизация родового пакета, который определяет тип, даст вам конкретный пакет, содержащий конкретный тип. Чтобы получить объект, потребуется еще один шаг. В C++ конкретизация дает объект сразу, не определяя конкретного класса. Чтобы определить другой объект, нужно просто конкретизировать шаблон снова:

C++

List<int>Int_List2; //Другой объект

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

Следующее различие между языками состоит в том, что C++ не использу­ет модель контракта, поэтому не исключено, что конкретизация вызовет ошибку компиляции в самом шаблоне (см. раздел 10.3).

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

Ранее обсуждалось порождение классов от одного базового класса, так что се­мейство классов образовывало дерево. При объектно-ориентированном про­ектировании, вероятно, класс будет иметь характеристики двух или несколь­ких существующих классов, и кажется допустимым порождать класс из не­скольких базовых классов. Это называется множественным наследованием (multiple inheritance). На рисунке 15.1 показано, что Airplane (самолет) может

быть многократно порожден из Winged_Vehicle (летательный аппарат с крыльями) и Motorized_Vehicle (летательный аппарат с мотором), в то время как Winged_Vehicle также является (единственным) базовым классом для Glider (планер). Задав два класса:

class Winged_Vehicle {

public:

void display(int);

C++

protected:

int Wing_Length; // Размах крыла

int Weight; // Bec

};

class Motorized_Vehicle {

public:

void display(int);

protected:

int Power; // Мощность

int Weight; // Bec

};

можно породить класс с помощью множественного наследования:

class Airplane:

C++

public Winged_Vehicle, public Motorized_Vehicle {

public:

void display_all();

};

Чтобы использовать множественное наследование, необходимо решить, что делать с данными и операциями, такими как Weight и display, которые насле­дуются из нескольких базовых классов. В языке C++ неоднозначность, вы­званная многократно определенными компонентами, должна быть явно раз­решена с помощью операции уточнения области действия:

void Airplane: :display_all()

{

C++

Winged_Vehicle::display(Wing_Length);

Winged_Vehicle::display(Winged_ Vehicle:: Weight);

Motorized_ Vehicle:: display(Power);

Motorized_ Vehicle:: display(Motorized_ Vehicle:: Weight);

};

Это нельзя считать удачным решением, так как вся идея наследования в том, чтобы допускался прямой доступ к данным и операциям базы, если не требуется их модификации. Реализовать множественное наследование на­много труднее, чем простое наследование, которое мы описали в разделе 14.4. Более подробно см. разделы с 10.1с по 10.1с упомянутого ранее справочного руководства по языку C++.

Значение множественного наследования в ООП является предметом для дискуссии. Некоторые языки программирования, такие как Eiffel, поддержи­вают использование множественного наследования, в то время как языки, по­добные Ada 95 и Smalltalk, не имеют таких средств. При этом утверждается, что проблемы, которые можно решить с помощью множественного наследо­вания, изящно решаются с использованием других средств языка. Например, выше мы отмечали, что родовые параметры теговых типов в языке Ada 95 можно использовать для создания новых абстракций, комбинируя уже суще­ствующие абстракции. Очевидно, что наличие возможности множественного наследования оказывает глубокое влияние на проектирование и программи­рование объектно-ориентированной системы. Таким образом, трудно гово­рить об объектно-ориентированном проекте, не зависящем от языка; даже на самых ранних стадиях проектирования вам следует ориентироваться на конк­ретный язык программирования.

5.2. Доступ к приватным компонентам

<<Друзья>> в языке C++

Внутри объявления класса в языке C++ можно включать объявление «друже-ственных» (friend) подпрограмм или классов, представляющих собой под-программы или классы, которые имеют полный доступ к приватным данным операциям класса:

class Airplane_Data {

private:

int speed;

friend void proc(const Airplane_Data &, int &);

friend class CL;

};

Подпрограмма ргос и подпрограммы класса CL могут обращаться к приват­ным компонентам Airplane_Data:

void proc(const Airplane_Data & a, int & i)

{

i = a.speed; // Правильно, мы — друзья

}

Подпрограмма ргос может затем передавать внутренние компоненты класса, используя ссылочные параметры, или указатели, как показано выше. Таким образом, «друг» выставил на всеобщее обозрение все секреты абстракции.

Мотив для предоставления такого доступа к приватным элементам взят из операционных систем, в которых были предусмотрены механизмы явного предоставления привилегий, называемых возможностями (capabilities). Это понятие меньше соответствует языкам программирования, потому что одна из целей ООП состоит в том, чтобы создавать закрытые, пригодные для по­вторного использования компоненты. Идея «друзей» проблематична с проектной точки зрения, поскольку предполагает, что компонент располагает знанием о том, кто им воспользуется, а это определенно несовместимо с идеей многократного использования компонентов, которые вы покупаете или заимствуете из других проектов. Другая серьезная проблема, связанная с конструкцией friend, состоит в слишком частом использовании ее для «за­плат» в программе, вместо переосмысления абстракции. Чрезмерное употреб­ление конструкции friend, очевидно, разрушит абстракции, которые были так тщательно разработаны.

Допустимо применение «друзей», когда абстракция составлена из двух самостоятельных элементов. В этом случае могут быть объявлены два класса, которые являются «друзьями» друг друга. Например, предположим, что клас­су Keyboard (клавиатура) необходим прямой доступ к классу Display (дисплей), чтобы воспроизвести эхо-символ; и наоборот, класс Display должен быть в состоянии поместить символ, полученный из интерфейса сенсор­ного экрана, во внутренний буфер класса Keyboard:

class Display {

Характеристики

Тип файла
Документ
Размер
2,54 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6418
Авторов
на СтудИзбе
307
Средний доход
с одного платного файла
Обучение Подробнее