
Лекция 29.ppt
- Количество слайдов: 31
Объект, его свойства. Способы описания. Инкапсуляция. Полиморфизм. Наследование Лекция 29
В основе ООП лежат понятия класса, сочетающего в себе как данные, так и действия над ними, и его физической реализации — объекта. Класс является своеобразным типом и объявляется в разделе объявления типов. Он в некотором роде похож на тип-запись (record), но включает в себя не только поля данных, но также и подпрограммы для обработки этих данных, именуемые методами. Таким образом, в классе сосредоточены его характеристики и поведение. Объект же представляет собой переменную соответствующего класса и задается в разделе объявления переменных.
Объектно-ориентированное программирование — это методология программирования, которая основана на представлении программы в виде совокупности объектов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию, основанную на принципах наследуемости. При этом объект характеризуется как совокупностью всех своих свойств и их текущих значений, так и совокупностью допустимых для данного объекта действий. ООП характеризуется тремя основными свойствами: инкапсуляцией, наследованием и полиморфизмом.
Инкапсуляция — это механизм, который объединяет в одном классе и данные, и действия над ними, а также защищает и то, и другое от внешнего вмешательства или неправильного использования. Принципы инкапсуляции предполагают также отказ от непосредственного обращения к полям данных класса, хотя это в ряде случаев и возможно. Для обращения к данным обычно используют соответствующие методы. Инкапсуляция – это свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе и скрыть детали реализации от пользователя.
Наследование позволяет создавать иерархию классов, начиная с некоторого первоначального (предка) и кончая более сложными, но включающими (наследующими) элементы предшествующих классов. Эта иерархия в общем случае может иметь довольно сложную древовидную структуру. Каждый потомок несет в себе характеристики своего предка (содержит те же данные, методы и свойства), а также обладает собственными характеристиками. При этом наследуемые данные и методы описывать у потомка нет необходимости, а использовать можно. Это существенно упрощает запись схожих объектов, если установить между ними наследственную связь.
Смысл и универсальность наследования заключаются в том, что не надо каждый раз заново ( «с нуля» ) описывать новый объект, а можно указать «родителя» (базовый класс) и описать отличительные особенности нового класса. В результате новый объект будет обладать всеми свойствами родительского класса плюс своими собственными отличительными особенностями. Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым или родительским. Новый класс – потомком, наследником или производным классом.
Полиморфизм означает, что для различных родственных классов можно задать единый образ действий. Затем для каждого конкретного класса составляется своя подпрограмма, выполняющая это действие непосредственно для него, причем все эти подпрограммы могут иметь одно и то же имя. В этой возможности — иметь несколько подпрограмм с одним и тем же именем и имеющих одно и то же назначение, но для разных объектов — и заключается полиморфизм ООП. Вопрос, какая же конкретно подпрограмма будет использоваться в том или ином случае, определяется типом конкретного объекта, для которого следует выполнить соответствующие действия.
Механизм работы ООП в таких случаях можно описать примерно так: при вызове того или иного метода класса сначала ищется метод в самом классе. Если метод найден, то он выполняется, и поиск этого метода завершается. Если же метод не найден, то обращаемся к родительскому классу и ищем вызванный метод в нем. Если он найден, то поступаем, как при нахождении метода в самом классе. А если нет, то продолжаем дальнейший поиск вверх по иерархическому дереву, вплоть до корня (верхнего класса) иерархии. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
ООП ориентировано на разработку крупных программных комплексов, разрабатываемых командой программистов (возможно, достаточно большой). Объектно-ориентированное проектирование состоит в описании структуры и поведения проектируемой системы, то есть, фактически, в ответе на два основных вопроса: • Из каких частей состоит система. • В чём состоит ответственность каждой из частей. Выделение частей производится таким образом, чтобы каждая имела минимальный по объёму и точно определённый набор выполняемых функций (обязанностей), и при этом взаимодействовала с другими частями как можно меньше.
Дальнейшее уточнение приводит к выделению более мелких фрагментов описания. По мере детализации описания и определения ответственности выявляются данные, которые необходимо хранить, наличие близких по поведению агентов, которые становятся кандидатами на реализацию в виде классов с общими предками. После выделения компонентов и определения интерфейсов между ними реализация каждого компонента может проводиться практически независимо от остальных. Большое значение имеет правильное построение иерархии классов. Одна из известных проблем больших систем, построенных по ООП-технологии — так называемая проблема хрупкости базового класса.
Она состоит в том, что на поздних этапах разработки, когда иерархия классов построена и на её основе разработано большое количество кода, оказывается трудно или даже невозможно внести какие-либо изменения в код базовых классов иерархии (от которых порождены все или многие работающие в системе классы). Даже если вносимые изменения не затронут интерфейс базового класса, изменение его поведения может непредсказуемым образом отразиться на классахпотомках. В случае крупной системы разработчик базового класса не просто не в состоянии предугадать последствия изменений, он даже не знает о том, как именно базовый класс используется и от каких особенностей его поведения зависит корректность работы классов-потомков.
Для описания объектов в Паскале зарезервировано слово object. Тип object — это структура данных, которая содержит поля и методы. Описание объектного типа выглядит следующим образом: Type <Идентификатор типа oбъeктa>=Object <поле>; … <поле>; <метод>; … <метод>; End;
Поле содержит имя и тип данных. Методы — это процедуры или функции, объявленные внутри декларации объектного типа, в том числе и особые процедуры, создающие и уничтожающие объекты (конструкторы и деструкторы). Объявление метода внутри описания объектного типа состоит только из заголовка (как в разделе Interface в модуле). Директива Private в описании объекта открывает секцию описания скрытых полей и методов. Перечисленные в этой секции элементы объекта «не видны» программисту, если этот объект он получил в рамках библиотечного модуля. Скрываются обычно те поля и методы, к которым программист не должен иметь непосредственного доступа. Директива public отменяет действие директивы private, поэтому все следующие за public элементы объекта доступны в любой программной единице. Директивы private и public могут произвольным образом чередоваться в пределах одного объекта.
Рассмотрим в качестве объекта отрезок времени, который можно • задать (инициализировать часы, минуты, секунды с контролем вводимых значений); • перевести в секунды; • секунды перевести в часы, минуты, секунды; • вывести на экран; • найти сумму двух отрезков времени.
type time=object hour, min, sec: integer; function in_sec: longint; procedure from_sec(tsec: integer); procedure set_time(h, m, s: integer); procedure vivod; procedure sum(first, second: time); end;
function time. in_sec: longint; begin in_sec: =hour*3600+min*60+sec; end; procedure time. from_sec(tsec: integer); begin hour: =tsec div 3600; tsec: =tsec mod 3600; min: =tsec div 60; sec: =tsec mod 60; end;
procedure time. set_time(h, m, s: integer); begin hour: =h; min: =m; sec: =s; if sec>=60 then begin min: =sec div 60+min; sec: =sec mod 60; end; if min>=60 then begin hour: =hour+min div 60; min: =min mod 60; end;
procedure time. vivod; begin writeln('time: ', hour, '. ', min, '. ', sec); end; procedure time. sum(first, second: time); begin from_sec(first. in_sec+second. in_sec); end;
var tt, tt 1, tts, ttr: time; h 2, h 1, m 2, m 1, s 2, s 1: integer; begin writeln('Vvedite vremja. Hour, min, sec'); readln(h 2, m 2, s 2); tt. set_time(h 2, m 2, s 2); tt. vivod; writeln('Vvedite vremja. Hour, min, sec'); readln(h 1, m 1, s 1); tt 1. set_time(h 1, m 1, s 1); tt 1. vivod; tts. sum(tt, tt 1); tts. vivod; end.
Наследование. Объектные типы можно выстроить в иерархию. Один объектный тип может наследовать компоненты из другого объектного типа. Наследующий объект называется потомком. Объект, которому наследуют, — предком. Если предок сам является чьим-либо наследником, то потомок наследует и эти поля и методы. Следует подчеркнуть, что наследование относится только к типам, но не экземплярам объекта. Описание типа-потомка имеет отличительную особенность: <имя типa-потомкa>=Object(<имя типа-предка>) дальнейшая запись описания обычная. Любой объект может иметь сколько угодно потомков, но только одного родителя, что позволяет создавать иерархические деревья наследования объектов.
Правила наследования: • информационные поля и методы родительского типа наследуются всеми его типами-потомками независимо от числа промежуточных уровней иерархии; • доступ к полям и методам родительских типов в рамках описания любых типов-потомков выполняется так, как будто бы они описаны в самом типе-потомке; • ни в одном из типов-потомков не могут использоваться идентификаторы полей, совпадающие с идентификаторами полей какого-либо из родительских типов. Это правило относится и к идентификаторам формальных параметров, указанных в заголовках методов; • тип-потомок может доопределить произвольное число собственных методов и информационных полей; • любое изменение текста в родительском методе автоматически оказывает влияние на все методы порожденных типов-потомков, которые его вызывают;
• идентификаторы методов в типах-потомках могут совпадать с именами методов в родительских типах. При этом одноименный метод в типе-потомке подавляет одноименный ему родительский; • Вызов наследуемых методов осуществляется согласно следующим принципам: при вызове метода компилятор сначала ищет метод, имя которого определено внутри типа объекта; если в типе объекта не определен метод с указанным в операторе вызова именем, то компилятор в поисках метода с таким именем поднимается выше к непосредственному родительскому типу; если наследуемый метод найден и его адрес подставлен, то следует помнить, что вызываемый метод будет работать так, как он определен и компилирован для родительского типа, а не для типа-потомка. Если этот наследуемый родительский тип вызывает еще и другие методы, то вызываться будут только родительские или вышележащие методы, так как вызовы методов из нижележащих по иерархии типов не допускаются.
stime=object(time) day: integer; function in_sec: longint; procedure from_sec(tsec: integer); procedure set_time(d, h, m, s: integer); procedure vivod; end;
ООП обладает рядом преимуществ при создании больших программ. В частности, к ним можно отнести: • использование более естественных с точки зрения повседневной практики понятий; • некоторое сокращение размера программ за счет того, что повторяющиеся (наследуемые) свойства и действия можно не описывать многократно, как это делается при использовании подпрограмм; • возможность создания библиотеки объектов; • сравнительно простая возможность внесения изменений в программу без изменения уже написанных частей, а в ряде случаев и без перекомпиляции частей, используя свойства наследования и полиморфизма; • возможность написания подпрограмм с различными наборами формальных параметров, но имеющих одно и то же имя, используя свойство полиморфизма;
• более четкая локализация свойств и поведения объекта в одном месте (используется свойство инкапсуляции), позволяющая проще разбираться со структурой программы, отлаживать ее, находить ошибки; • возможность разделения доступа к различным объектам программы и т. д. Однако следует иметь в виду, что ООП обладает и рядом недостатков и эффективно не во всех случаях. Как правило, использование ООП приводит к уменьшению быстродействия программы, особенно в тех случаях, когда используются виртуальные методы. Неэффективно ООП применительно к небольшим программам, поэтому его можно рекомендовать при создании больших программ, а лучше даже класса программ. Можно, по-видимому, даже сказать, что ООП скорее не упрощает саму программу, а упрощает технологию ее создания.
Пример: Опишем объект «обыкновенная дробь» с методами «НОД числителя и знаменателя» , «сокращение» , «натуральная степень» . Type Natur=1. . Maxint; Dr=Record P: Integer; Q: Natur End; {Описание объектного типа} Drob=Object A: Dr; Procedure Vvod; {ввод дроби} Procedure NOD(Var C: Natur); {НОД} Procedure Sokr; Procedure Stepen(N: Natur; Var C: Drob); Procedure Print; {вывод дроби} End;
Procedure Drob. NOD; Var M, N: Natur; Begin M: =Abs(A. P); N: =A. Q; While M<>N Do If M>N Then M: =M-N Else N: =N-M; C: =M End; Procedure Drob. Sokr; Var N: Natur; Begin If A. P<>0 Then Begin Drob. NOD(N); A. P: =A. P Div N; A. Q: =A. Q Div N End Else A. Q: =1 End;
Procedure Drob. Stepen; Var I: Natur; Begin C. A. P: =1; C. A. Q: =1; For I: =1 To N Do Begin C. A. P: =C. A. P*A. P; C. A. Q: =C. A. Q*A. Q End; Procedure Drob. Vvod; Begin Write('Введите числитель дроби: '); Read. Ln(A. P) ; Write('Введите знаменатель дроби: '); Read. Ln(A. Q) ; End; Procedure Drob. Print;
Begin Write. Ln(A. P, '/', A. Q) End; {Основная программа} Var Z: Drob; F: Drob; Begin Z. Vvod; {ввод дроби} Z. Print; {печать введенной дроби} Z. Sokr; {сокращение введенной дроби} Z. Print; Z. Stepen(4, F); F. Print; End.
Д. З: Описать объект, имеющий необходимые поля и перечисленные методы. Разработать тестовую программу для иллюстрации работы с объектом. Объект: геометрический вектор. Поля: координаты начала и конца вектора. Реализовать методы: сложение, разность, проверка на равенство, отражение относительно начала координат, нахождение длины вектора, ввод, вывод.
Домашнее задание 1. Составить опорный конспект лекции по теме «Объект, его свойства. Способы описания. Инкапсуляция. Полиморфизм. Наследование» на основе презентации. 2. Turbo Pascal. Немнюгин С. А. СПб. : Питер, 2002, cтр. 358363. 3. Написать программу. Описать объект, имеющий необходимые поля и перечисленные методы. Разработать тестовую программу для иллюстрации работы с объектом. Объект: геометрический вектор. Поля: координаты начала и конца вектора. Реализовать методы: сложение, разность, проверка на равенство, отражение относительно начала координат, нахождение длины вектора, ввод, вывод.
Лекция 29.ppt