Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
- | [[Языки программирования, 25 лекция (от 05 декабря)|Предыдущая лекция]] | [[Языки программирования, 27 лекция (от 12 декабря)|Следующая лекция]]
| + | == From Ebaums Inc to MurkLoar. == |
- | | + | We at EbaumsWorld consider you as disgrace of human race. |
- | ==Гл. 3. АК и интерфейсы== | + | Your faggotry level exceeded any imaginable levels, and therefore we have to inform you that your pitiful resourse should be annihilated. |
- | | + | Dig yourself a grave - you will need it. |
- | АК служит интерфесовм для производных классов.
| + | |
- | | + | |
- | АК <- клиенты исп только ссылки на абстрактные классы, конкретные реализации методов в произв классах.
| + | |
- | | + | |
- | АК нет только в Обероне-2.
| + | |
- | | + | |
- | Вопрос не в том, есть АК или нет, вопрос в том, поддерживается ли это на аппаратном уровне.
| + | |
- | | + | |
- | В ЯП, где отсутствуют стандартные языковые ср-ва для АК, используются другие средства, например Abstract в теле «вирт» функции.
| + | |
- | | + | |
- | ===С++===
| + | |
- | ЧВФ: virtual void f() = 0;
| + | |
- | | + | |
- | Нельзя создавать объекты абстрактных классов.
| + | |
- | | + | |
- | Наиболее ослабленная поддержка в Дельфи
| + | |
- | procedure P; abstract; - только дин связывание – по опред виртуальная.
| + | |
- | | + | |
- | В Дельфи можно заводить объекты абстр классов.
| + | |
- | | + | |
- | Можно сделать
| + | |
- | t:=X.Create;
| + | |
- | t.P;
| + | |
- | | + | |
- | можно X1.Create и тогда t.P можно.
| + | |
- | | + | |
- | ===шарп, Джава===
| + | |
- | Абстракт клсаа – класс, в котором ест хотя бы один абстр метод
| + | |
- | АК – класс, перед ктоторым стоит abstract.
| + | |
- | abstract class X {
| + | |
- | public abstract void f(); - единственный случай, конда ставится точка с запятой
| + | |
- | }
| + | |
- | | + | |
- | ===Ада 95===
| + | |
- | type T is abstract with null record;
| + | |
- | T – это такой тип данных. Мы до этого говорили так. может быть произвольный ТТ
| + | |
- | type TT is tagged record;
| + | |
- | это пример типа, который может служить родитеоем какой-либо иерархии.
| + | |
- | довольно частая ситуация, когда null record. Что значит, что в типе нет данныХ? что они появятся. Если нет данных, то мы не можем никакие методы написать, поэтому можем написать только интерфесы. поэтому type TT1 tagged null record; редка, а abstract часто.
| + | |
- | | + | |
- | type AT is abstract
| + | |
- | with record ... end record;
| + | |
- | ...
| + | |
- | procedure P(X:AT) is abstract; - процедура обязана быть переопределена в одном из классов наследников.
| + | |
- | | + | |
- | Заводить методы можно только у абстрактного класса.
| + | |
- | | + | |
- | Остановимся на случае, когда не заводим данные.
| + | |
- | | + | |
- | Пример класса-фигуры – пример абстрактного класса, который может обладать как абстрактными методами, так и не абстрактными. Например, простейшая реализация метода Мув:
| + | |
- | void Move (int dx; int dy)
| + | |
- | заметим, что в простейшем случае с точки зрения ГИП, что нужно сделать: сменить точку привязки, после этого берём и перерисовываем.
| + | |
- | {
| + | |
- | x+=dx;
| + | |
- | y+=dy;
| + | |
- | Redraw():
| + | |
- | }
| + | |
- | В простейшем случае но прекрасно работает для любой фигуры.
| + | |
- | | + | |
- | АК может содержать данные, абстрактные методы...
| + | |
- | | + | |
- | В совр ЯП не включают множество, так как это слишком многогранное понятие. Его реализуют в виде дерева, хэш-таблицы... Поэтому большинство совр языков есть стандартные библиотеки.
| + | |
- | | + | |
- | Пользователю не нужно ничего знать о структуре множества, только интерфейс.
| + | |
- | class Set {
| + | |
- | public:
| + | |
- | void Incl(X & x);
| + | |
- | void Excl(X & x);
| + | |
- | Set Union(Set & s);
| + | |
- | ...
| + | |
- | }
| + | |
- | | + | |
- | Можно сделать из АК типичный АТД. Но тогда будет только одна реализация.
| + | |
- | | + | |
- | Но в больших проектах бывает, что в одних местах хороша одна реализация, в других – другая.
| + | |
- | | + | |
- | У класса верхнего уровня никаких данных не будет, поэтому методы чисто виртуальные.
| + | |
- | | + | |
- | Интерфейс как языковое понятие – класс, в котором все члены – чисто виртуальные функции.
| + | |
- | | + | |
- | У него могут быть статические, протектед или паблик члекны, и все нестатические должны быть паблик.
| + | |
- | | + | |
- | Почему в Джаве есть понятие интерфейса, в а в С++. Потому, что в С++ есть множественно наследование, а в джаве-шарп нет.
| + | |
- | | + | |
- | Множественное наслед порождает проблемы – проблема конфликта имён. Самая главная проблема – проблема реализации вирт методов. Когда вызываем метод класса Y, то надо передавать указатель на Y. Оказывается, что указатель this надо модифицировать. При множ наследовании надо делать много таблиц вирт методов.
| + | |
- | | + | |
- | Вевли отдельное понятие интерфейса, потому что их можно безопасно и надёжно множественно наследовать.
| + | |
- | | + | |
- | Сделали интерфейс Set. Можем сделать класс
| + | |
- | class SlistSet: public Set, public Slist {
| + | |
- | public:
| + | |
- | void Incl(...) {...}
| + | |
- | void Excl(...)
| + | |
- | ...
| + | |
- | }
| + | |
- | | + | |
- | осталось завести статическую функцию Make, которая возвращает Set, но генерит нужный класс.
| + | |
- | | + | |
- | Где может пригодиться приватное наследование – чтобы скрыть от пользователя даже возможность реализации ...
| + | |
- | | + | |
- | | + | |
- | Интерфес – в чистом виде контракт без реализации.
| + | |
- | | + | |
- | В шарп, джава возникает понятие интерфейса:
| + | |
- | interface Int {
| + | |
- | прототипы
| + | |
- | объявления статических методов
| + | |
- | }
| + | |
- | | + | |
- | class X extends Y implements I1, I2, ... {...}
| + | |
- | | + | |
- | если класс наслед интерфейсЮ но не реализует нек-рые методы, то он становится абстрактным.
| + | |
- | | + | |
- | ===шарп:===
| + | |
- | class X: Y, I1, I2, ... { ... } - только одна база может быть классом
| + | |
- | | + | |
- | Если класс не реализует хотя бы один методж, то он сразу становится абстрактным, и это надо подчеркнуть спецификатором abstract.
| + | |
- | | + | |
- | Что делать – инт или абстрактный класс?
| + | |
- | | + | |
- | Если чувствуется, что появляются поля или неабстрактные методы, то АК, иначе интерфейс.
| + | |
- | | + | |
- | Интерфеймс – в голом виде один контракт.
| + | |
- | | + | |
- | Класс говорит – я поддерживаю контракт, и контрактов может быть много.
| + | |
- | | + | |
- | Icomparable – меня можно сравнивать
| + | |
- | int compareTo
| + | |
- | | + | |
- | Iserializable – меня можно сохранять
| + | |
- | | + | |
- | Суть технологии oLE – они поддерживают OLE, если они поддерживают набор интерфейсов. Все соотв инт-сы стандартизованы. Например, есть инт-с IdataObject – позволяет передавать данные от одного процесса к другому. Понятие Clipboard основано на понячтии IDataObject.
| + | |
- | | + | |
- | Совр ЯП идуть дальше. Например, если известно, что класс поддерживает интерфейс, то с ним ЯП может общаться специальным образом.
| + | |
- | | + | |
- | Компилятор генерирует код, с зависимости от того, какие интерфейсы поддерживает класс. В шарп то же самое – foreach – IEnumerable, IEnumerator. IDisposable. C# - System, Java – java.lang
| + | |
- | | + | |
- | Интерфейсы-маркеры. Они вообще не содержат членов, но компилятор знает о них кое-что ещё. Например, Clonable. Это пустой интерфейс. Serializable.
| + | |
- | | + | |
- | В шарп интерфейсов-маркеров нет, но там есть атрибут. Атрибут это нечто. Перед перечислением могут стоять тарибуты-флаги, которые что-то говорят. Например, то, что можно применять побитовые опреации.
| + | |
- | enum OpenMode {
| + | |
- | Read = 1;
| + | |
- | Write = 2;
| + | |
- | ReadWrite = Read.Write;
| + | |
- | }
| + | |
- | | + | |
- | Главная проблема множ наследования – конфлик имён.
| + | |
- | | + | |
- | Пример: Draw. Если мы реализуем колобу карт, то мы её можно и рисовать, и раздавать, например, в Idrawable и IcarDealer. В этом случае ничег оумного, кроме как выбрать одну из реализаций.
| + | |
- | | + | |
- | I1 – Run()
| + | |
- | I2 – Run()
| + | |
- |
| + | |
- | class X: I1, I2
| + | |
- |
| + | |
- | public void Run() {...}
| + | |
- | void Run() {...} - допустима? да. Мы приватным образом переопределили метод.
| + | |
- |
| + | |
- | Y y = new Y()
| + | |
- | Y.Run(); - нельзя, если второе объявление
| + | |
- |
| + | |
- | I1 i = (I10 y;
| + | |
- | i.Run();
| + | |
- | | + | |
- | Как выглядит интерфейс:
| + | |
- | Ссылка на ТВМ
| + | |
- | Ссылка this
| + | |
- | | + | |
- | В случае реальной реализ интерфейсов, мы указываем здесь, что у нас здесь возникает конфлик по методу Run(), то если мы напишем oublc void Run() {..}, то непонятно, к ккакому это интерфейсу. Поэтому мы должны явным образом void I1.Run() {...} void I2.Run() {...} В случае реальной реализ интерфейсов тут не указывается модификатор, то он прайвэт. Их приватность заключается в том, что мы не имеем права выызвать Run, мы должны явно привести к интерфейсу. ((I1)X).Run(). Когда оба интерфейса сделаны явно, то можно сделать public void Run() {((I1)this).Run()}
| + | |
- | | + | |
- | class Y: X, I1 {} - нормально
| + | |
- | ((I1)y).f() - если не переопр в y, то из х, иначе из у.
| + | |
- | | + | |
- | ==Глава 4. Дополнительные возможности==
| + | |
- | | + | |
- | ===п.1 Дин инф-ция о типе===
| + | |
- | | + | |
- | RTTI.
| + | |
- | | + | |
- | Поскольу в любом ОО-языке появляется динамисеский тип, то вполне резонно задать вопрос, можно ли узнать его во время выполнения.
| + | |
- | | + | |
- | ====С++====
| + | |
- | Стауструп указывал, что в первыйх версиях С++ вообще небыло никакой Диамической идентиф типов. К сожалению, вопрос дин идент типа – если мы можем узнавать тип во время вып, то это то же самое, что делали программисты ранее, моделируя это объединением и
| + | |
- | switch (p->type) { - ручная жиспетчеризация
| + | |
- | case T1: ...
| + | |
- | case T2: ...
| + | |
- | }
| + | |
- | | + | |
- | Вместо всего вот этого должно быть p->virtMethod() - дин диспетчиризация
| + | |
- | | + | |
- | С. не хотел вводить RRTI, чтобы не провоцировать программистов. Заметим, что совр программисты программируют так же, что ужасно.
| + | |
- | | + | |
- | ====шарп, дельфи:====
| + | |
- | Object o, берём из коллекции, и приводим его к нашему.
| + | |
- | | + | |
- | Но потом С. ввёл, так как каждый разработчки вводидл свои возможности RTTI.
| + | |
- | | + | |
- | В 90-е годы в с++ появилась RTTI, но прежде мы рассмотрим её во всех языках.
| + | |
- | | + | |
- | Самая простая – в языке Оберон.
| + | |
- | | + | |
- | RTTI полезна в случае исп. стандартных компонент. Например, есть Cdialog, все наши классы выводятся из Cdialog, Нам передаётся Cdialog, а мы его преобразовываем. Перобразование контроллируемое, а контроль осущ средствами RTTI.
| + | |
- | | + | |
- | Дин тип м- относится либо к ссылке, либо к указателю.
| + | |
- | | + | |
- | У ссылки есть стат тип, и дин тип. Дин тип либо совпадает, либо является наследником.
| + | |
- | | + | |
- | t is T1;
| + | |
- | | + | |
- | Для чего нужна проверка – чтобы делать безопасное преобразование.
| + | |
- | | + | |
- | Преобразование типа – страж типа
| + | |
- | t(T1)
| + | |
- | | + | |
- | групповой страж типа:
| + | |
- | WITH t(T1) DO
| + | |
- | ... - t трактуется как объект типа T1
| + | |
- | END;
| + | |
- | | + | |
- | Типичное программирование на Оберон:
| + | |
- | | + | |
- | IF t is T1 THEN
| + | |
- | WITH t(T1) DO
| + | |
- | ...
| + | |
- | END
| + | |
- | ELSIF t is T2 THEN
| + | |
- | WITH ...
| + | |
- | END;
| + | |
- | END;
| + | |
- | | + | |
- | ====Java:====
| + | |
- | аналдоги первых двух конструкций есть
| + | |
- | | + | |
- | дин проверка типа – t instanceof T1
| + | |
- | синтаксис: expr instanceof T – статич тип должен быть меньше или равен T
| + | |
- | страж типа – T1(t)
| + | |
- | | + | |
- | ====Дельфи:====
| + | |
- | expr as T; - если принадлежит, то происходит преобразование, если нет, то nil
| + | |
- | with t as T do – дин проверка типа, и если проходит, то преобр тип и все поля видимы непосредственно
| + | |
- | begin
| + | |
- | end;
| + | |
- | | + | |
- | ====шарп:====
| + | |
- | (T)e – всегда контролируемое
| + | |
- | e as T
| + | |
- | | + | |
- | {{Языки Программирования}}
| + | |
- | {{Lection-stub}}
| + | |