лекция 19 (Языки программирования (лекции) (2008))

2019-09-19СтудИзба

Описание файла

Файл "лекция 19" внутри архива находится в папке "Языки программирования (лекции) (2008)". Документ из архива "Языки программирования (лекции) (2008)", который расположен в категории "". Всё это находится в предмете "языки программирования" из 7 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .

Онлайн просмотр документа "лекция 19"

Текст из документа "лекция 19"

Языки программирования.

Лекция 19.

Часть 2: Объектно-ориентированные ЯП

Язык называется ООЯП, если:

1. В нём есть понятие объекта, причем не просто понятие объекта, а оно предполагает понятие типа данных и инкапсуляции (можно определять свои защищенные абстракции).-объектный

2. Понятие наследования

3. Полиморфизм (перекрытие операций, одному знаку можно сопоставить несколько значений)

- статический ( форму оператора выбирает компилятор на этапе трансляции , исходя из типов операндов- статический полиморфизм; также используется с понятиями "родовые модули"(Ада, С++- шаблоны, С#)).

- динамический полиморфизм имеет смысл, когда со знаком смысл связывается виртуально (зависит от динамического типа).

Глава 1. Наследование в ЯП

Это означает, что между двумя типами создаётся связь "наследование"

Эти типы называются базовый класс (суперкласс) и производный класс (полукласс). Производный класс (ПК) обладает всеми свойствами базового класса (БК).

Свойства: мн-во операций + мн-во значений

В языке Ада есть понятие выведение нового типа

Type T1 is new T;

Тип Т1 наследует мн-во значений и все операции типа Т, но это новый тип!

Отличие от наследования:

У нас дополнительных свойств не появляется. Мы могли ограничивать свойства, но расширять не могли.

А при наследовании ПК может расширяться новыми данными и операциями.

В языке Оберон появляется понятие "расширения типа".

Все старые свойства сохраняются, но могут появляться новые данные, новые методы.

У нас все языки делились на языки с классами(и тип и контейнер) и на модульные языки.

К числу модульных ООЯП относится Ада95 и Оберон (Оберон-2).

Язык Оберон - язык с наследованием, но без динамического связывания. В Оберон-2 добавлено ещё и динамическое связывание.

Другая группа ООЯП с классами- С++, Дельфи, Ява, С#.

Проблема( основная ):

Любой ли тип может расширяться? Расширяться может любой тип, являющийся записью.

Любая ли запись может расширяться?

Есть 2 точки зрения:

- любой тип данных может быть расширен - это точка зрения языка Оберон и С++ (любой тип данных может являться основой некоторой иерархии).

В языке Оберон есть некоторый тип данных - запись:

TYPE T=RECORD

X:INTEGER;

END;

T1 = RECORD(T)-наследование Т1 расширяет Т путем добавления к Х Y

Y:REAL;

END;

C++:

class X {

int a;

}

class Y: модификатор X {

double b;

};

модификатор = public, private или protected

Права доступа могут меняться, но только в сторону ужесточения.

Этот модификатор говорит о том, что если он public - то ничего не меняется (в классе У права доступа к членам классам Х). При private - все члены класса Х не доступны из У. При protected все члены public класса Х становятся protected класса У .

X *px = &y;- преобразование указателей, через которые можно снять запреты.

Во всех остальных языках права доступа при наследовании не изменяются.

Ада, С++ и Дельфи с точки зрения дизайна должны были обеспечивать совместимость с предыдущими своими версиями:

- В С++ понятие класса настолько общее, что структуры класса С могут трактоваться как классы. struct отличается только правилами умолчания доступа.(по умолчанию у struct - public)

- Но в языке Ада поступили по-другому и не могли поступить иначе, т.к. этот язык очень богатый. Там сделали то,. что наследовать можно было только специальный тип данных.

- Как и в паскале, в Дельфи есть обычное понятие record. Но есть и понятие class, которое уже можно наследовать. Появился специальный класс(TObject), из которого все наследуется

type T = class (TObject)

...

end;

То же самое и в Аде 95. Есть тип запись.

А вот с точки зрения наследования появился специальный тип - тегированная запись - tagged record:

type T = tagged record

x,y:integer;

end record;

Такая запись может быть вершиной наследования--> наследовать можно только специально выделенный тип (тэгированная запись). Если нет tagged, то эта старая программа на Аде, если есть , то включаются все объектно-ориентированные (ОО) черты. Это было сделано для совместимости с Ада 83.

Реальное наследование в Аде 95 происходит следующим образом:

type T1 is new T

with record

z:real;

end record;

Это похоже на обычную запись, но Т - тегированная запись.z-новое поле.

При наследовании можем ничего и не добавлять, так в С++:

class Y: public X {

}

Это означает, что класс У - то же самое, что Х.

Зачем вводить такие клоны?

1). Чем это отличается от typedefX Y; ?

В последнем случае Y - не новый тип данных, и ему нельзя делать перекрытие:

void f(X);

void f(Y);

2). Если Х-шаблон, то чтобы не таскать за собой конкретизацию, можно просто использовать наследование.

Если на языке Ада мы просто наследуем тегированный тип данных и ничего не добавляем, то пишем:

type T1 is new T

with null record;

Без with Т1-ы новый тип ни коим образом несовместимый с Т

В языках C# и Java синтаксис

таков:

class Y: X {...};- С #

class Y extends X {...};- Java

Теперь поговорим об общем и разном:

- Каждый новый унаследованный класс создаёт новую область видимости. Это во всех ООЯП, кроме Оберона (новые члены добавляют в область видимости). Раз есть новая область видимости, то за счёт того, что новая - вложенная область видимости, здесь (в новом классе) новые члены могут переопределяться (имеют такие же имена). Но обратиться к старым именам ещё можно.

В Обероне же только одна область видимости и переопределение запрещено.

К старым членам мы обращаемся только в функциях членах и извне. Рассмотрим пример:

class X {

int a;

...;

}

class Y: public X{

int a;

void f()

}

Обращаться можно при помощи синтаксиса:

имя_класса::имя_члена или имя_класса.имя_члена только внутри ф-ий -членов

К а получить доступ извне можно следующим способом:

Y y;

y.a; // к а из Y

((X)y).a; // C# and Java

X(y).a; // Java

- ООЯП существенно нарушают основную парадигму ЯП - "объект принадлежит одному и только одному типу данных". В ООЯП каждый объект принадлежит типу данных. Если у этого типа данных есть базовые классы (прямые или косвенные), то объект принадлежит и базовым классам. Но не наоборот!

Как следствие, объекты одного и того же типа данных можно присваивать друг другу:

X - базовый класс

Y - производный класс

x = y; // неявное преобразование

Но меняет ли это преобразование тип объекта?

void f(X x) {

x;

}

Y y;

f(y); ~ f(X(y));- из производного в базовый

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

Линейная организация памяти:

base

x

y

T1 z

T2

Оберон, Ада, С++ - копирование:

тип Y

x

y

z

тип Х

х

y

В языке SmallTalk чуть по-другому.

Цепная организация:

Y X


zzzz

Присваивание x = y никак не меняет тип у, так как нам нужно было бы динамически изменять память.

Обратное присваивание запрещено - не будут определены новые поля производного класса.

От производного класса можно выделить базовую часть.

Теперь рассмотрим указатели и ссылки на объекты:

void f(X &x);

Указатели на объекты имеют:

-статический тип

- динамический тип данных.

Статический тип данных - это то, на что ссылка или указатель ссылаются.

Динамический тип данных: если допустимо присваивание x = y, то и мы можем присвоить указателю на Х указатель на Y(тип, который в данный момент указывает указатель).


Х Y

С точки зрения указателей: х=y <> y=x

Для динамических указателей справедливы те же самые правила.

Класс T1=>T2

x = y; // correct

y = x; // INCORRECT!

Вопрос: почему? Ведь указатели - не объекты, они имеют одинаковый размер. Но ведь дальше мы будем разыменовывать ссылку и можем обратиться за границы базового объекта.

Т. е. преобразование из производного в базовый, но нет преобразования из базового в производный (но в С++ мы можем написать его сами).

У нас языки делятся на 2 больших класса:

  • языки с объектно-ссылочной семантикой (ОСС) - Джава, С# и Дельфи - там все объекты являются ссылками .

  • языки без ОСС - Ада95, С++, Оберон.В обероне ссылки- параметры переменные.

Но во всех этих языках есть понятие ссылок и указателей.

Оберон:

PROCEDIRE P(X:t);

PROCEDURE PP(VAR X:T); // динамический тип Х здесь меняется

Y:T1;

P(Y);

Зачем нужен динамический тип? Он нужен для динамического связывания.

Глава 2: Динамическое связывание

Без динамического связывания наследование смысла не имеет.

Отношение между объектами:

Отношение ссылки - один объект ссылается на другой;

Отношение вложения - один объект содержит внутри себя другой;

Отношение наследования - похоже на отношение вложения;

Динамическое связывание - связывание в зависимости от динамического типа.

Рассмотрим вызов метода:

x.f();

class X() {

...

void f();

};

На функцию f() никаких накладных расходов

void g(X *p); // на класс X никаких накладных расходов

Для каждой функции из Х генерируется специальная функция с уникальным именем void f......_X()(X *this) {...}(уникальность: а) уник. имя класса б).уник.имя ф-ии внутри класса с). уник. профиль параметров ф-ии); Поэтому на виртуальные функции никаких накладных расходов не несут. Фактически, это обычные внешние функции, только имена их локализованы внутри класса Х.

Для статических функций - аналогично, но не передаётся указатель this.

Для виртуальный функций: их поведение зависит от типа указателя (зависит от динамического типа).

Если функция описана как виртуальная

class X {

virtual void f() {cout << "X::f";};

void g() {cout << "X::g";};

};

При наследовании каждый раз возникает вложенная область видимости.

Если у нас образуется класс Y:

class Y:public X {

void f() { cout << "Y::f";};

void g();

}

Если функция g() не виртуальная, то она просто закрывает функцию из своего родителя. А если функция уже виртуальная, то её никак объявить не виртуальной нельзя.

Для виртуальной функции(если она ранее объявлена как виртуальная, то далее даже без указания она будет виртуальная) есть специальный процесс "подмена" - overriding - функция f() не то, что скрывает внешнюю функцию, а то, что виртуальные функции с одним именем обязаны иметь один профиль + для них применяется механизм динамического вызова.

Например,

X=>Y=>Z и в каждом класс есть виртуальная функция f().

Если речь идет об объекте, который обладает динамическим типом (например, X *px;):

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