- •Программирование и алгоритмические языки. Курс за третий семестр. Введение в объектно-ориентированное программирование (ооп)
- •Именование типов в Object Pascal Тип данных «класс»
- •Инкапсуляция
- •Представление данных Данные как функции доступа Свойства
- •Иерархия типов Наследование реализации Проблемы наследования
- •Полиморфизм
- •Проблема множественности иерархий Агрегирование
- •Абстрактные методы и именованные интерфейсы
- •Описание сложного поведения
- •Эволюция пользовательского интерфейса
- •Автоматные модели описания поведения Сложное поведение как изменчивое поведение
- •Программы как символьные преобразования Алфавит как тип данных
- •Программы как синхронные преобразования
- •Тривиальное поведение
- •Нетривиальное поведение
- •Интеллект как рефлексивное, самоопределяемое поведение Машины Тьюринга
- •События как предикаты
- •Событийно управляемое исполнение программ в ооп Программы как тип данных
- •События конечного пользователя и системные, внешние и внутренние
- •Обработка исключений Делегирование
- •Живые данные
- •Задача (проблема) многих тел
- •События как исключения Исключения как события Обработка исключений в Delphi
Программирование и алгоритмические языки. Курс за третий семестр. Введение в объектно-ориентированное программирование (ооп)
Мы манипулируем типами. Как мы это делаем? Единственной предпосылкой таких рассуждений является именование типов. Именуем ли мы типы?
В процедурном программировании понятие типа всё ещё сильно ориентировано на значения. Именуются области значений, а не собственно тип как var. Вспомним, что классификация типов также производилась по области значений.
Модульное программирование уже допускает именование типа, если отождествлять модуль с реализацией типа, как это делали мы. В реальности ни синтаксис, ни общепринятая практика не связывают понятие модуля с понятием типа. Это библиотека, то есть произвольный набор определений значений и преобразований. Скажем, можно трактовать модуль как определение нескольких типов.
Именование типов в Object Pascal Тип данных «класс»
В самом простом случае синтаксис типа таков:
(имя класса)=class
(список полей Field1,…,Fieldk)
(список объявлений (заголовков) методов: Method1,…,Methodn)
end;
Fieldi – в точности как при описании типа «запись», только с некоторыми дополнительными опциями. Methodi – заголовок процедуры или функции как в интерфейсе модуля с некоторыми дополнительными опциями.
Семантика: именованный тип данных.
Объявление (определение) класса помещается в интерфейсной части модуля (interface) определением методов; заголовки вместе с реализацией, телом процедуры или функции – в списке реализации (implementation).
Как обычно, можно в другом модуле сослаться на данное представление с помощью предложения uses и обычным образом определить переменные такого типа.
uses (имя модуля, содержащего определение класса);
var x: (имя класса);
Переменные типа «класс» называются объектами. В реальности определяется не сам объект, а ссылка на него – факт, который в синтаксисе явным образом не указывается нигде. Как переменные динамического типа, сами объекты создаются и уничтожаются в ходе выполнения. Среди методов класса явно выделяют конструкторы – процедуры создания объекта по ссылке и деструкторы, что явным образом отражается в синтаксисе.
constructor C(FP);
destructor D(FP); где FP – список формальных параметров.
Как правило, конструкторы называют Create, деструкторы – Destroy.
Порождение объекта: p:=(имя класса).Create(FP|), где FP| - фактические параметры.
После порождения объекта можно обращаться к его полям и методам с помощью обычной точечной нотации: p.M(FP|)
Уничтожаются объекты обычно не с помощью Destroy, а с помощью процедуры p.Free, которая сначала проверит, определена ли ссылка. Если да, то обращается к методу Destroy.
Пример.
interface
type tRational=class
числитель, знаменатель: integer;
{арифметика}
procedure Добавить (a: tRational );
procedure Вычесть (a: tRational );
procedure Домножить (a: tRational );
procedure Поделить (a: tRational );
{ввод-вывод}
procedure Читать (var f: text);
procedure Написать (var f: text);
{присваивания}
procedure Присвоить (a: tRational );
procedure Присвоить (x,y: integer); override
end;
implementation
procedure tRational.Добавить (a:tRational);
begin
числитель:=числитель*a.Знаменатель+знаменатель*а.Числитель;
знаменатель:=знаменатель*а.Знаменатель;
end;
{и так далее}
uses UnitRational;
{y:=(b1+b2)*(b1+2)}
var b1,b2,y: tRational;
begin
b1:=tRational.Create;
b2:=tRational.Create;
y:=tRational.Create;
b1.Читать(f);
b2.Читать(f);
y:=b1; {Семантическая ошибка: присвоение ссылок, а не их значений}
y.Присвоить(b1);
y.Добавить(b2);
*************
b1.Free;
b2.Free;
y.Free;
end;
Помимо базовой семантики класса как именованного типа оно связывается с дополнительными способами описания и использования абстрактных типов, которые обычно формулируются в терминах трёх основных понятий: инкапсуляция, наследование и полиморфизм.