Тема 4. ООП (продолжение).pptx
- Количество слайдов: 19
Основы ООП (продолжение)
Задание на практику 1) Приватность (сокрытие данных). Программа создает класс Pet. Описать имя питомца и его вид (name, species) и сделать эти поля скрытыми (приватными). Описать свойства, позволяющие менять данные поля из основной программы. 2) Смерть пришельца (обмен сообщениями между двумя классами). Программа создает hero - экземпляр класса Player и Invader - экземпляр класса Alien. При вызове метода blast() объекта hero с аргументом invader этот объект вызывает метод diе() объекта invader. Другими словами, когда герой стреляет в пришельца, это значит, что объект «герой» посылает объекту «пришелец» сообщение с требованием умереть.
Полиморфизм (от греч. "много форм") - это свойство классов, связанных наследованием, иметь различную реализацию входящих в них методов, и способность переменной базового класса вызывать методы того класса, объект которого содержится в этой переменной в момент вызова метода. Полиморфизм используется в ситуации, когда для группы взаимосвязанных объектов требуется выполнить единое действие, но каждый из этих объектов должен выполнить указанное действие по-своему (т. е. у действия возникает много форм). Для этого определяется базовый для всех объектов класс с виртуальными методами, предусмотренными для меняющегося поведения, после чего эти методы переопределяется в потомках.
Полиморфизм type Base = class public procedure Print; begin writeln('Base'); end; Derived = class(Base) public procedure Print; begin writeln('Derived'); end; var b: Base : = new Derived; b. Print; Какая версия метода Print вызывается - класса Base или класса Derived?
Полиморфизм В данном случае решение будет принято еще на этапе компиляции: вызовется метод Print класса Base, заявленного при описании переменной b. Говорят, что имеет место раннее связывание имени метода с его телом. Если же решение о том, какой метод вызывать, принимается на этапе выполнения программы в зависимости от реального типа объекта, на который ссылается переменная b, то в таком случае вызывается метод Derived. Print (говорят также, что имеет место позднее связывание). Методы, для которых реализуется позднее связывание, называются виртуальными, а переменная базового класса, через которую осуществляется вызов виртуального метода, полиморфной переменной. Таким образом, полиморфизм реализуется вызовом виртуальных функций через переменную базового класса. Тип класса, который хранится в данной переменной на этапе выполнения, называется динамическим типом этой переменной.
Полиморфизм Для того чтобы сделать метод виртуальным, следует в объявлении этого метода после заголовка указать ключевое слово virtual с последующей ; . Для переопределения виртуального метода следует использовать ключевое слово override. type Base = class public procedure Print; virtual; begin writeln('Base'); end; Derived = class(Base) public procedure Print; override; begin writeln('Derived'); end; var b: Base : = new Derived; b. Print; Теперь же вызывается метод Print класса Derived за счет того что решение о вызове метода откладывается на этап выполнения программы.
Виртуальность Говорят, что методы Print завязаны в цепочку виртуальности. Чтобы разорвать ее (не вызывать методы в подклассах виртуально) используется ключевое слово reintroduce:
Виртуальность Если мы хотим начать новую цепочку виртуальности, то следует использовать и virtual и reintroduce: Если переопределить виртуальную функцию невиртуальной без ключевого слова reintroduce, то ошибки не произойдет - будет выведено лишь предупреждение о том, что цепочка виртуальности нарушена. При переопределении виртуального метода в подклассе его уровень доступа должен быть не ниже, чем в базовом классе. Например, public виртуальный метод не может быть переопределен в подклассе privateметодом.
Абстрактные методы Методы, описанные в базовом классе с помощью заголовка и не имеющие тела, предназначенные для переопределения в подклассах, объявляются с ключевым словом abstract и называются абстрактными. Данные методы являются виртуальными, но ключевое слово virtual использовать не нужно. type Shape = class private x, y: integer; public constructor Create(xx, yy: integer); begin x : = xx; y : = yy; end; procedure Draw; abstract; end;
Абстрактные классы Классы, содержащие абстрактные методы, также называются абстрактными. Экземпляры этих классов создавать нельзя. Классы с абстрактными методами используются как "полуфабрикаты" для создания других классов. Использование override при переопределении абстрактных методов обязательно, поскольку абстрактные методы являются разновидностью виртуальных. type Point = class(Shape) public procedure Draw; override; begin Pit. Pixel(x, y, Color. Black); end;
Статические поля и методы В классе можно объявить так называемые классовые (статические) поля и методы. Они не принадлежат конкретному экземпляру класса, а связаны с классом в общем (они существуют даже тогда, когда нет ни одного экземпляра класса). Для их вызова используется точечная нотация, причем, перед точкой используется не имя объекта, а имя класса. Чтобы поле или метод сделать классовым (статическим), перед его именем следует указать ключевое слово class. Определим для класса Person количество созданных объектов этого класса как статическое поле и организуем доступ к этому полю на чтение с помощью статической функции. После каждого вызова конструктора значение статического поля будет увеличиваться на 1.
Статические поля и методы type Person = class private name: string; age: integer; class cnt: integer : = 0; public constructor (n: string; a: integer); begin cnt += 1; name : = n; age : = a; end; class function Count: integer; begin Result : = cnt; end; Begin var p: Person : = new Person('Иванов', 20); var p 1: Person : = new Person('Петров', 18); writeln(Person. Count); // обращение к классовому //методу Count end.
Перегрузка операций - это средство языка, позволяющее вводить операции над типами, определяемыми пользователем. В Pascal. ABC. NET можно использовать только предопределенные значки операций. Перегрузка операций для типа T, являющегося классом или записью, осуществляется при помощи статической (классовой) функции-метода со специальным именем operator. type Complex = record re, im: real; class function operator+(a, b: Complex): Complex; begin Result. re : = a. re + b. re; Result. im : = a. im + b. im; end; class function operator=(a, b: Complex): boolean; begin Result : = (a. re = b. re) and (a. im = b. im); end;
Перегрузка операций Для перегрузки операций действуют следующие правила: 1. Перегружать можно все операции за исключением @ (взятие адреса), as, is, new. Кроме того, можно перегружать специальные бинарные операции +=, -=, *=, /=, не возвращающие значений. 2. Перегружать можно только еще не перегруженные операции. 3. Тип по крайней мере одного операнда должен совпадать с типом класса или записи, внутри которого определена операция. 4. Перегрузка осуществляется с помощью статической функции-метода, количество параметров которой совпадает с количеством параметров соответствующей операции (2 - для бинарной, 1 - для унарной). 5. Перегрузка операций +=, -=, *=, /= для соответствующих операторов осуществляется с помощью статической процедуры-метода, первый параметр которой передается по ссылке и имеет тип записи или класса, в котором определяется данная операция, второй - передается по значению и совместим по присваиванию с первым. Перегрузка остальных операций осуществляется с помощью статических функций-методов. 6. Типы интерфейсов не могут быть типами параметров. Причина: типы параметров должны вычисляться на этапе компиляции. 7. Операции приведения типа задаются статическими функциями, у которых вместо имени используется operator implicit (для неявного приведения типа) или operator explicit (для явного приведения типа).
Анонимные классы Иногда необходимо сгенерировать объект класса на лету, не описывая класс. У такого класса нет имени (он анонимный), но известен набор полей. var p : = new class(Name : = 'Иванов', Age : = 20); Println(p. Name, p. Age); У объекта p автоматически генерируются публичные поля Name и Age соответствующих типов. Два объекта принадлежат к одному анонимному классу если они имеют одинаковый набор полей, и эти поля принадлежат к одинаковым типам. var p 1 : = new class(Name : = 'Петров', Age : = 21); p 1 : = p;
Анонимные классы Если поля безымянного класса инициализируются переменными, то имена полей можно не писать - они генерируются автоматически и их имена и типы совпадают с именами и типами переменных. var Name : = 'Попова'; var Age : = 23; var p : = new class(Name, Age); Println(p. Name, p. Age); Поля безымянного класса можно также инициализировать переменной с составным именем, имеющим точечную нотацию. В этом случае в качестве имен полей берутся последние имена в точечной нотации. var d : = new Date. Time(2015, 5, 15); var p : = new class(d. Day, d. Month, d. Year); Println(p. Day, p. Month, p. Year); Println(p);
Автоклассы При описании класса перед словом class можно поставить слово auto. Такие классы называются автоклассами. Для автоклассов автоматически генерируется конструктор с параметрами, инициализирующими все поля класса, а также метод To. String, выводящий значения всех полей класса (в отличие от действия writeln по умолчанию выводятся значения не только публичных, а всех полей). type Person = auto class name: string; age: integer; end; var p : = new Person('Иванов', 20); // конструктор автокласса генерируется автоматически writeln(p); // вызывается сгенерированный автоматически метод To. String
Задание на практику 1) Полиморфизм. Создать базовый класс «Матрешка» и описать виртуальный метод выводящий на экран сообщение «Самая большая матрешка» . Создать 5 классов матрешек поменьше и описать цепочку виртуальности данного метода. 2) Абстрактные классы. Создать абстрактный класс «Человек» и абстрактный метод «Работать» и статический метод «Количество человек» . Унаследовать несколько новых классов и переопределить абстрактный метод. 3) Перегрузка операций. Создать класс «Комплексное число» . Описать методы ввода и вывод комплексного числа, умножения и деления двух комплексных чисел, возведение в квадрат комплексного числа.
Домашнее задание 1. Создать игру «Томагочи» . Можно выбирать имя питомца. Описать меню в котором можно совершать с питомцем несколько действий (играть, кормить, уложить спать и т. д. ); 2. Создать класс обыкновенная дробь, поля класса – числитель и знаменатель. Методы класса: возведение дроби в степень, вывод дроби. В классе предусмотреть методы перегрузки операций: сложение, вычитание, деление и умножение дробей.


