Лекция 20 (лекции (2002))

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

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

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

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

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

Объекты абстрактного класса нельзя заводить в памяти. На объекты этого класса можно ссылаться с помощью указателей и ссылок, при этом реально они будут указывать на какие-то объекты производных классов, которые часто называют конкретными классами. Концепция абстрактного класса оказалась очень удобной с точки зрения ООП, поскольку идея объектно-ориентированного дизайна состоит в том, что все свойства, которые нам нужны, мы формируем в виде функционального интерфейса, и пользователи работают с объектами соответствующего типа данных только через этот функциональный интерфейс. Абстрактный класс предоставляет такой функциональный интерфейс, а конкретизироваться он будет уже в конкретных классах. Это позволяет достаточно гибкое расширение, поскольку пользователь, работая с указателями и ссылками на абстрактные классы, работает только с наиболее общими свойствами, которые могут быть по-своему реализованы в каждом конкретном классе. Поскольку эта концепция важна, она естественным образом вошла в другие языки программирования. И в языке Java, и в языке C#, и в языке Delphi есть специальный спецификатор abstract. В C#, Java

public abstract class X{

public abstract void f( );

}

Если класс абстрактный, то впереди обязательно должен стоять спецификатор absract. Кроме того, ключевое слово abstract должно стоять перед каждой функцией, которая не реализована (абстрактная функция). Не для абстрактных функций мы должны писать тело. Точно также как и в С++ эти объекты не могут размещаться с помощью new (другого способа размещения объектов в этих языках нет).

Синтаксис Delphi очень сильно схож с этим. Главное отличие от языков C# и Java, что в Delphi можно порождать объекты абстрактных классов, но при этом компилятор выдает предупреждение, что в этом классе не все функции определены. В любом случае, при попытке обратиться к абстрактному методу будет порождаться исключение, которое теоретически можно ловить с помощью механизма обработки исключений. Мы можем по ошибке явно вызвать абстрактную функцию, сняв виртуальность.

Абстрактный класс - это класс, в котором есть хотя бы одна абстрактная функция. Представим себе наиболее абстрагированный абстрактный класс, в котором все функции являются чистыми виртуальными, и в котором, как следствие, отсутствуют данные. В языке С++ для такого класса будет одна неабстрактная функция – конструктор, которая даже если мы не укажем ее явно всегда будет генерироваться. Конструктор, в отличии от деструктора, не может быть виртуальным. Полностью абстрактный класс, или интерфейс (этот термин можно видеть даже в книгах по С++, хотя в этом языке понятие интерфейса нет) – класс, в котором все функции являются чистыми виртуальными функциями и который не содержит никаких данных. В памяти допустима следующая реализация такого класса (класс состоит из одного указателя на ТВМ)

ссылка на ТВМ

Пример: реализация множеств.

В ранних языках программирования (например, в языке ФОРТРАН и его производных) был базисный тип данных множество. В современных языках встроенный базисный тип данных множество отсутствует. Понятие множества можно реализовывать совершенно по-разному. В реализациях Паскаля и его наследников (Модула-2, Оберон) понятие множество присутствует только как битовая шкала. Это одна из возможных реализаций множества, и она хороша, для того, чтобы можно было напрямую и достаточно элегантным образом адресовать бит внутри машинного слова. Другой вариант множества – это действительно некоторое множество - контейнер каких-то объектов. Один из вариантов – чтобы не зависеть от реализации множества вообще – чтобы пользователь просто работал с множеством, а как оно реализовано для него не важно. Опишем класс Set как абстрактный.

class Set{

virtual void Incl(T & x) = 0; -включение элемента

virtual void Excl(T & x) = 0; -исключение элемента

virtual bool IsIn(T & x) = 0;

}

Пользователю необходимо знать только этот интерфейс. Различные реализации из одного класса Set могут получаться с помощью множественного наследования. Например

class Slist_Set: public Slist, public Set{

};

Slist – класс, который реализует однонаправленный список. Другой пример

сlass Seek_Set: public BitScale, public Set{

};

BitScale – класс, который эффективно реализовывает битовую шкалу. Можно все это еще реализовать с помощью шаблонов, чтобы не зависеть от типа данных Т. Классы Slist_Set, Seek_Set выступают только на уровне реализации. При порождении нового объекта, мы обращаемся к конструктору нужного нам класса, но пользователь всегда работает с помощью Set. Например, у нас может быть некоторая статическая функция для соответствующего класса

Set * MakeSet( ){

return new Slist_Set;

};

Для того, чтобы сменить реализацию соответствующего класса, необходимо фактически сменить только реализацию функции MakeSet. Например, поставить вместо Slist_Set BitScale. Типы возвращаются разные. Поскольку класс Set базовый, то возвращается ссылка на него. То, что и интерфейс, и реализация класса находятся в одном месте приводит к тому, что изменение структуры класса с точки зрения реализации, приводит к перекомпиляции всех клиентов, которые используют этот тип данных. В нашем случае клиентам необходимо знать только заголовочный файл, в котором находится интерфейс класса Set. В результате, чтобы изменить реализацию нам нужно изменить реализацию одной функции (интерфейс всегда будет один и тот же), что не вызывает перетрансляции клиентов. Это очень интересное свойство динамического связывания и виртуальных функций. Понятие интерфейса – это как раз то понятие, которое связывает воедино концепцию абстрактного типа данных и концепцию наследования. Интерфейсы выступают как некоторые абстрактные функциональные интерфейсы конкретных типов данных. Все, что мы сказали об абстрактных типах данных, естественно, относится и интерфейсам. В более молодые, чем С++, языки программирования понятие интерфейса вошло явным образом. В частности и в языке C#, и в языке Java оно присутствует как языковое понятие. Проблемы, которые возникают при реализации множественного наследования в языке С++, связанные с механизмом реализации динамического связывания виртуальных методов, в случае множественного наследования, при котором только один класс наследуется по данным, а все остальные классы являются интерфейсами, не возникают. Например

public interface Set{

void Incl(object o);

void Excl(object o);

}

Тут никаких abstract писать не надо. Нет смысла упрятывать от кого-то функции интерфейса, т.к. интерфейс – это то, что мы экспортируем для того, чтобы пользователь мог работать с конкретной реализацией класса через абстрактный интерфейс. Поэтому, естественно, по умолчанию все члены интерфейса считаются публичными. В языке Java интерфейс кроме объявлений функций-членов (которые, естественно, будут абстрактными - без реализации) также может содержать набор констант, т.е. статических финальных переменных.

public interface Set{

void Incl(object o);

void Excl(object o);

static final int NUL = 0;

}

final в языке Java говорит о том, что это константа, а static – что она не является членом соответствующего класса. В языке C# вместо статических констант (они там особо не нужны) выступают перечислимые типы данных, которые в Java отсутствуют. Т.е. в C# интерфейс кроме объявления функций может также содержать объявления перечислимых типов. Больше ничего в интерфейсе не допускается. Интерфейс нужен для того, чтобы описывать свойства различных конкретных классов с абстрактной точки зрения. Поскольку в нем нет данных, интерфейс выступает как ссылка на ТВМ. Если к нему теперь добавить еще указатель на сам объект, то через интерфейс можно работать с конкретным объектом. Например, с точки зрения реализации в этих языках интерфейс может выступать как пара указателей. Первый указатель – это указатель на ТВМ, а второй указатель – это указатель на сам объект. Либо он может выступать как некоторая пара: указатель на объект, вначале которого всегда находится ссылка на полную таблицу виртуальных методов, + смещение d в соответствующей ТВМ.

В Java наследование выглядит следующим образом

class X extends Y implements I1, I2, …{ …};

(class X extends Y {…}; - обычное (одиночное) наследование (extends – расширяет).) I1, I2, … - имена интерфейсов. Очевидно, можно заводить переменные типа интерфейс, а им будут присваиваться объекты классов, которые реализуют этот интерфейс. Например можно писать

I1 i = new X;

при условии, конечно, что Х не является абстрактным классом.

Если класс описан таким образом, но не реализует хотя бы один из методов интерфейса, он, очевидно, будет абстрактным, и перед ним должно стоять ключевое слово abstract (если не стоит – компилятор выдает ошибку). Класс Х будет конкретным только в том случае, если он реализует все функции данных интерфейсов.

d

полная ТВМ


Y d

I1

I2

d показывает на какую именно часть ТВМ мы должны ссылаться. Очень простая реализация. Не возникает никаких проблем с реализацией за счет того, что наследование по данным единичное (члены-данные класса Х – это члены-данные класса Y).

В языке C# синтаксис следующий

class X: Y, I1, I2, … {…}

В списке Y, I1, I2, … только одно имя может быть не интерфейсом. Если все имена являются интерфейсами никакого противоречия не будет.

Понятие интерфейса оказывается достаточно гибким. Абстрактный класс, у которого все функции абстрактные, отличается от интерфейса тем, что класс всегда может иметь как конкретные функции так и конкретные данные. Класс – это, в общем случае, уже какая-то конкретная реализация какого-то понятия. Например, Set – это интерфейс, в отличии от Slist.

Что имеет смысл выделять в интерфейс, когда объект достаточно многолик? Обычно смотрят на то, какого рода свойства должен реализовывать объект. Чаще всего с помощью интерфейса мы выражаем свойства, которые не специфичны для данного объекта. Например, в языке Java есть стандартный интерфейс, который называется Cloneable. Именно в этот интерфейс входит функция

object Clone( );

Так решена проблема копирования в языке Java. Поскольку это ссылочный язык, то, естественным образом, при копировании объекта копируется только ссылка – так называемое поверхностное копирование. Если нужно глубокое копирование, надо вызывать метод Clone. Метод Clone в типе данных Object. Свойство копироваться – это не специфичное свойство какого-то конкретного класса, это свойство всех объектов вообще. Поэтому вполне резонно, что класс Object описан таким образом

class Object implements Cloneable …

Он, в частности, реализует в себе среди прочих и интерфейс Cloneable. Это не единственный интерфейс, который реализует класс Object.

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