ИНКАПСУЛЯЦИЯ И СВОЙСТВА ОБЪЕКТА
ВВЕДЕНИЕ В ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ Исторически сложилось так, что программирование возникло и развивалось как процедурное программирование, которое предполагает, что основой программы является алгоритм и процедуры обработки данных. Но в ООП проще думать и разрабатывать большие, сложные продукты Концепция ООП разработана для увеличения производительности программиста, приближение процесса программирования к процессу человеческого мышления и стандартизацию как программ, так их и подхода к ним. Три основополагающих принципа объектно-ориентированного программирования (ООП): инкапсуляция, наследование, , полиморфизм В объектно-ориентированном программировании основой является объект и класс. Объект — это некоторая структура, соответствующая объекту реального мира и его поведению (то есть некая совокупность данных и способов работы с ними). Например: кнопка или поле ввода. Задача, решаемая с использованием методики ООП, описывается в терминах объектов и операций над ними, а программа при таком подходе представляет собой набор объектов и связей между ними. Объект в целом предназначен для решения какой-либо отдельной конкретной задачи и воспринимается в программе как неделимое целое (т.е. нельзя из объекта «выдернуть» отдельное поле(свойство) или метод(функцию)). Все объекты, имеющие однотипное поведение или как принято говорить в ООП, обладающие общими методами, составляют один класс. Примечание Строго говоря, для разработки приложения в Delphi на базе компонентов, предоставляемых средой разработки, знание концепции ООП не является необходимым. Однако материал данной главы будет весьма полезен для более глубокого понимания того, как программа взаимодействует с компонентами, что и почему Delphi добавляет в текст программы.
КЛАСС Языки PascalABC (иObject Pascalначиная с 8 версии) поддерживают концепцию объектно-ориентированного программирования, так же как и Язык Delphi и дает возможность определять классы . Класс— это сложный тип данных схожий с комбинированным типом (records) , но включающий в себя, помимо описания полей данных, еще описание процедур и функций, которые могут быть выполнены над переменной этого типа данных (класса) и для обработки ее полей. В терминологии ООП данные класса называются полями ( или свойствами) и служат для хранения информации об объекте., а процедуры и функции — называются методами. предназначенные для обработки полей.
Описание класса имеет вид: type Пример объявления простого класса: type TPerson = class Private f_name: string[15]; //поле f_address: string[35];//поле f_age: integer; Public procedureShow; // объявление (декларация) метода
end; Примечание: Согласно принятому в Delphiсоглашению, имена полей должны начинаться с буквы f (от слова field — поле).
Поля и методы образуют интерфейс класса Еще пример объявления класса: type constructor {procedure} ТStudent.Create(nm: string; c,gr: integer); Например, класс TForm (формы) содержит различные виды форм: пустую форму, форму для ввода пароля, форма «О программе» и т. д. Свойства у этих форм разные (цвет, размер, названия и т. д.), а поведение одинаковое (открываются, закрываются, перемещаются и т. д.).
ОБЪЕКТ Объект - представитель классаили другими словами – переменная этого типа (класса) и объявляется в программе в разделе var Например: Var stud1, stud2 : Тstudent ; professor: TPerson;
Пример Объектом в Delphi может являться компонент Edit2илиButton3/ Var Edit2:TEdit; Button3:TButton;
Объект в целом предназначен для решения какой-либо конкретной задачи и воспринимается в программе как неделимое целое (т.е. нельзя из объекта «выдернуть» отдельное поле или метод).
КОНСТРУКТОР И ДЕСТРУКТОР
В Delphi объект — это динамическая структура. Переменная-объект содержит не данные, а ссылку на данные объекта. Поэтому программист должен позаботиться о выделении памяти для этих данных. Выделение памяти осуществляется при помощи специального метода класса (процедуры) — конструктора, которому обычно присваивают имя Create (создать). Для того чтобы подчеркнуть особую роль и поведение конструктора, в описании класса вместо слова procedure используется слово constructor.( по синтаксису языкаPascalABCиObject PascalиDelphi) Ниже приведено описание класса TPerson, в состав которого введен конструктор: type TPerson = class Private fname: string [ 15 ]; faddress: string[35]; f_age: integer; constructor Cireate; // конструктор Public procedure show; // метод end; constructorTPerson.Create; Begin fname := ''; faddress := ''; f_age:=0; end;
Var professor: TPerson; Например, после выполнения инструкции professor := TPerson.Create; -выделяется необходимая память для всех данных объекта professor и им присваиваются пустые строки. (Инициализация) Помимо выделения памяти, конструктор, как правило, решает задачу присваивания полям объекта начальных значений, т. е. осуществляет инициализацию объекта. Пример 2, constructor ТStudent.Create(nm: string; c,gr: integer); Var stud1, stud2 : Тstudent; …………… Stud1:=TStudent.Create('Иванов',1,3); stud2:=TStudent.Create; // инициализация пустыми и нулевыми полями
После объявления и инициализации объект можно использовать, например, установить значение поля объекта. Доступ к полю осуществляется указанием имени объекта и имени поля, которые отделяются друг от друга точкой. Например, для доступа к полю fname объекта professorнадо написать professor.fname:=’ Сидоров‘ ; Пример 2, stud1.name:='Синичкин'; Если в программе какой-либо объект больше не используется, то можно освободить память, занимаемую полями данного объекта. Для выполнения этого действия используют метод-деструктор Free. ? destructor TStudent.Destroy; begin ??? end; Например, для того, чтобы освободить память, занимаемую полями объекта professor, достаточно записатьprofessor.Free; stud1.Destroy;
professor..Destroy;
МЕТОД
Методы класса – это процедуры и функции, объявление которых включено в описание класса. Они выполняют действия над объектами класса. Для того чтобы метод был выполнен (вызвать процедуру), необходимо указать имя объекта и имя метода, отделив одно имя от другого точкой. Например, инструкция professor. Show; - вызывает применение метода show к объекту professor. Пример 2, stud2.print; stud2.nextCourse; Методы класса объявляются в программе точно так же, как и обычные процедуры и функции, за исключением того, что имя процедуры или функции, являющейся методом, состоит из двух частей: имени класса, к которому принадлежит метод, и имени метода. Имя класса от имени метода отделяется точкой. Ниже приведен пример определения метода show класса TPerson // метод Show класса TPerson procedureTPerson.Show; Begin ShowMessage( 'Имя:' + fname + #13 + 'Адрес:' + faddress +#13+’возраст:’ + f_age); end; или Пример 2, procedure TStudent.Print; Begin writeln('Имя:',name,' курс:',course,' группа:',group); end; procedure TStudent.NextCourse; Begin Inc(course); end;
Примечание: В инструкциях метода ( в описании процедуры) доступ к полям объекта осуществляется без указания имени объекта. type Student=class name: string; course: integer; group: integer; constructor Create(nm: string; c,gr: integer); destructor Destroy; procedure Print; procedure NextCourse;
end;
constructor Student.Create(nm: string; c,gr: integer); begin name:=nm; //course:=c; if (C < 0) or (c>5) then begin WriteLn('...Некорректно задан курс (', c, ')!'); course := 0; end else course:=C; group:=gr; end; procedure Student.Print; begin writeln('Имя:',name,' курс:',course,' группа:' ,group); end; procedure Student.NextCourse; begin Inc(course); // course;=course+1; end; destructor Student.Destroy; begin WriteLn('...Вызван деструктор класса Student - ...уничтожается объект класса '); end; var s1,s2: Student;
M : Real;
begin WriteLn('Лабораторная работа №2'); s1 := student.Create; s1.Print; s2 := student.Create('BATYA',1,2); s2.Print; end.
type CComplex = class //(TObject) Re : Real; Im : Real; end; var MyObject : CComplex; M : Real; begin WriteLn('Лабораторная работа №1'); WriteLn('Задача 1. Класс CComplex.'); MyObject := CComplex.Create; WriteLn; WriteLn('Введите действительную и мнимую части ', 'комплексного числа:'); ReadLn( MyObject.Re, MyObject.Im ); WriteLn; M := sqrt(sqr(MyObject.Re) + sqr(MyObject.Im)); WriteLn('Модуль комплексного числа равен ', M : 8 : 3); MyObject.Destroy;
end. type CComplex = class //(TObject) Re : Real; Im : Real; function Abs : Real; constructor Create; destructor Destroy; end; function CComplex.Abs : Real; var Res:Real; begin WriteLn('...Вызван метод Abs класса Complex'); WriteLn('...вычисляется модуль комплексного числа.'); Res := sqrt ( sqr(Re) + sqr(Im) ); Abs := Res end; constructor CComplex.Create; begin WriteLn('...Вызван конструктор класса CComplex -'); WriteLn('...создается объект класса CComplex.') end; destructor CComplex.Destroy; begin WriteLn('...Вызван деструктор класса CComplex - ...уничтожается объект класса CComplex.'); end;
var MyObject : CComplex; M : Real;
begin WriteLn('Лабораторная работа №1'); WriteLn('Задача 2. Метод Abs() класса CComplex.'); MyObject := CComplex.Create; //- вызов стандартных функций WriteLn; WriteLn('Введите действительную и мнимую части ', 'комплексного числа:'); ReadLn( MyObject.Re, MyObject.Im ); WriteLn; M := sqrt(sqr(MyObject.Re) + sqr(MyObject.Im)); WriteLn('Модуль комплексного числа равен ', M : 8 : 3);
WriteLn('Оператор M := MyObject.Abs(); '); M := MyObject.Abs; WriteLn('Модуль, вычисленный методом Abs, равен ', M:8:3);
MyObject.Destroy; //вызов стандартных процедур
end. type Digit=class x,y:real; function sum:real; function Razn_k(k:integer):real; Constructor Create (xx,yy:real); //Destructor Destroy ; end; function Digit.sum:real; begin sum:=x+y; end; function Digit.Razn_k(k:integer):real; begin razn_k:= power(x-y,k); end; Constructor Digit.Create (xx,yy:real); begin if xx>0 then x:=xx; if yy>0 then y:=yy; end; //Destructor Digit.Destroy ; var para1,para2: Digit; s1,vr1:real; begin para1:= Digit.Create(4,23) ; writeln(para1.x,' ', para1.y); s1:=para1.sum; writeln(s1); s1:=para1.razn_k(5); writeln(s1); end. Пример 3, описание метода Button1Click будет выглядеть так: interface type TForml = class(TForm) Buttonl: TButton; procedure Button1Click(Sender: TObject); end; implementation procedure TForml.Button1Click(Sender: TObject); begin Close; end;…….. Основные принципы ООП
Три основополагающих принципа объектно-ориентированного программирования (ООП): инкапсуляция, наследование, , полиморфизм
ИНКАПСУЛЯЦИЯ И СВОЙСТВА ОБЪЕКТА Инкапсуляцией называется объединение трех сущностей класса – полей, методов и свойств в единое целое (складывание их в одну «капсулу»). Инкапсуляция делает класс «самодостаточным» для решения конкретной задачи. Например, класс TForm содержит (инкапсулирует в себе) все необходимое для создания Windows-окна, Например, класс TEdit инкапсулирует в себе все необходимое для создания текстового поля и т.д. Инкапсуляция представляет собой мощное средство обмена готовыми к работе программными заготовками. Библиотеки классов DELPHI – это набор «кирпичиков», созданных Borland для построения «многоэтажных зданий» ваших программ. Под инкапсуляцией также понимается сокрытие полей и обеспечение доступа к ним только через специальные методыкласса (свойства). (Это нужно для обеспечения безопасности и уменьшения риска ошибочных действий над полями объектов ,например возрасту присвоить отрицательное значение) Чтобы поля сокрыть в описании класса указывается слово Private перед описанием скрываемых полей, а перед открытыми данными – Public. (По умолчанию все Public.) Доступ к сокрытым полям реализуется при помощи свойств объекта. Свойства занимают промежуточное положение между полями и методами. Свойство состоит из поляи двух методов, обеспечивающих доступ к этому полю и попутно выполняющих некоторые действия, например проверку допустимости значения поля. В описании класса перед именем свойства записывают слово property (свойство). После имени свойства указывается его тип, затем — имена методов: функция чтения после слова read и процедура записи после слова write. Синтаксис: property <имя свойства>: <тип> read <имя функции чтения> write <имя процедуры записи>; Функция чтения и процедура записи должны быть методами этого класса и иметь следующий вид: function get<имя свойства>: тип; Пример: Type TPerson=class private f_age: integer; F_name:string; Address:string; ConstructorCreate(………); ProcedureShow; ... procedure SetAge(age: integer); Begin if age>0 then f_age:=age else writeln('Ошибка в Person.setAge: возраст не может быть отрицательным'); // это для Pascal ,а для Delphi ShowMessage('Ошибка’); end; function GetAge: integer; Begin writeln('Осуществлен доступ к полю f_age на чтение'); Result:=f_age; //GetAge:= f_age; end; publiс property Age: integer read getAge write setAge;... end; Var prof:TPerson; prof.Age:=47; prof.Name:=’А.А. Сидоров’; prof.Address:=’Ленина’; ………
Пример.Описание свойств. type TNewClass = class(TObject) private FCode: integer; FSign: char: FNote: string; published property Code: integer read FCode write FCode; property Sign: char read FSign write FSign; property Note: string read FNote write FNote; end; Пример3.Описание свойств. interface type // описание класса CPatient – «Пациент» CPatient = class F_Name: string; // имя F_Age : Integer; // возраст F_Diagnosis : string; // диагноз F_t : Real; // температура constructor Create(N : string; A : Integer); destructor Destroy; function getTemp : Real; procedure setTemp(new_t : Real); property Temp : Real read getTemp write setTemp; end;
implementation
constructor CPatient.Create(Name : string; Age : Integer); begin WriteLn(‘Создается объект класса ’); F_Name := Name; if Age < 0 then begin WriteLn(‘...Некорректно задан возраст (’, Age, ‘)!’); Age := 0 end else f_Age := Age; end;
procedure CPatient.setTemp(new_t : Real); begin if new_t < 20 then begin WriteLn( Name,' скорее мертв, чем жив... '); F_Diagnosis := ‘Труп’; end else F_t := new_t; if (new_t> 41) or (new_t < 34) then WriteLn(‘...Критическое значение температуры (’,New_t ‘)!’);
end;
function CPatient.getTemp() : Real; begin if (t > 36.4) and (t < 36.8) then WriteLn(‘...Температура в норме.’); if (t <= 36.4) and (t > 35) then WriteLn(‘...Температура понижена!’); if (t <= 35) then WriteLn(‘...Температура низкая!!!’); if (t >= 36.8) and (t < 38) then WriteLn(‘...Температура повышена!’); if (t >= 38) then WriteLn(‘...Температура высокая!!’); if (t >= 40) then WriteLn(‘...Температура очень высокая!!!’); getTemp := f_t; // или result:=F_t; end; var
Patient1, Patient2: CPatient; begin Patient1 := CPatient.Create(‘Иванов’, 40); Patient2 := CPatient.Create(‘Сидоров’, 27); ShowMessage(Patient1.f_Name + ‘ - ’+ Patient1.F_age); Patient1.Temp := Random(151) /10.0 + 30; WriteLn(‘ОШИБКА В ЛЕЧЕНИИ!’); Patient2.Temperature := Random(20); WriteLn(‘.у Сидорова температура=.’, Patient2.Temperature, ‘диагноз =’, Patient2.F_Diagnosis); Patient1.destroy; Patient2.destroy;
end.
Ниже приведен пример описания класса TPerson, содержащего два свойства: NameиAddress. Type TName = string[15]; TAddress = string[35]; TPerson = class // класс Private FName: TName; // значение свойства Name FAddress: TAddress; // значение свойства Address f_age: integer; ConstructorCreate(Name:Tname); ProcedureShow; FunctionGetName: TName; FunctionGetAddress: TAddress; ProcedureSetAddress(NewAddress:TAddress); Public PropertyName: Tname // свойство Name readGetName; // доступно только для чтения разрешить только чтение PropertyAddress: TAddress // свойство Address readGetAddress // доступно для чтения writeSetAddress; // и записи … … end; // метод получения значения свойства Name FunctionTPerson.GetName; Begin Result:=FName; end; // метод получения значения свойства Address functionTPerson.GetAddress; Begin Result:=FAddress; end; // метод изменения значения свойства Address ProcedureTPerson.SetAddress(NewAddress:TAddress); Begin if FAddress =' ' thenFAddress := NewAddress; end; В программе для установки значения свойства надо записать обычную инструкцию присваивания значения свойству.
Например, чтобы присвоить значение свойству Address объекта student, достаточно записать var student: TPerson; student.Address := 'С.Петербург,ул.Садовая 21, кв.3'; Например 2, Var prof:TPerson;... prof.Age:=35; В Delphi Значение свойства объекта можно задавать либо в Инспекторе объектов, либо прописывать в программном коде Например, Form1.Visible:= false. В программе на методы свойства можно возложить некоторые дополнительные задачи. Например, с помощью метода можно проверить корректность присваиваемых свойству значений, установить значения других полей, логически связанных со свойством, вызвать вспомогательную процедуру. В приведенном выше описании класса TPerson свойство Name доступно только для чтения, а свойство Address — для чтения и записи. Попытка присвоить значение свойству, предназначенному только для чтения, вызывает ошибку времени компиляции. Установить значение свойства, защищенного от записи, можно во время инициализации объекта. . Приведенный конструктор объекта TPerson создает объект и устанавливает значение поля FName, определяющего значение свойства Name. // конструктор объекта TPerson ConstructorTPerson.Create(Name:TName); Begin FName:=Name; end; // метод получения значения свойства Name FunctionTPerson.GetName; Begin Result:=FName; end;
Операторы, обеспечивающие создание объекта класса TPerson и установку его свойств, могут быть, например, такими: student := TPerson.Create('Иванов'); student.Address := 'ул. Садовая, д.3, кв.25'; student.Age:=17; if student.Name='Иванов'then inc(student.Age);
НАСЛЕДОВАНИЕ Наследованиепозволяет объявить новый класс на основе уже существующего (базового) класса. (для упрощения создания (описания) новых объектов) Новый класс (потомок) наследует свойства и методы базового (родительского) класса и может быть обогащен новыми возможностями. Смысл наследования заключается в следующем: если нужно создать новый класс, лишь немного отличающийся от старого, то нет необходимости в переписывании заново уже существующих полей и методов. В этом случае объявляется новый класс, который является наследником уже имеющегося, и к нему добавляются новые поля, методы и свойства. Такой механизм получения новых классов называется порождением. Процесс образования подкласса – специализация. Процесс образования суперкласса – обобщение. Например, У базового класса TButton (кнопка) есть дочерние классы BitBtn (кнопка с рисунком и надписью) и TSpeedButton (кнопка с рисунком). При объявлении класса-потомка указывается класс родителя. Например, класс TEmployee (сотрудник) может быть порожден от рассмотренного выше класса TPerson путем добавления поля FDepartment (отдел). Объявление класса TEmplioyeeв этом случае может выглядеть так: Type TEmployee = class(TPerson) FDepartment: integer; // номер отдела constructor Create(Name:TName; Dep:integer); end; Правила наследования 1. Объект-наследник (потомок) получает все поля и методы предка. 2. Потомок может (хотя и не обязательно) добавить: собственные поля, методы или перекрыть своими методами одноимённые унаследованные методы. 3. Любой тип–потомок может быть родительским для других типов. В этом случае новый тип наследует поля всех своих предков . 4. Доступ к полям и методам родительских типов в описании типов – потомков выполняется так, как будто они описаны в самом типе-потомке. 5. Имена методов в родительских и дочерних типах могут совпадать. В этом случае метод дочернего типа «перекрывает» метод родительского.
Популярное: Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас... Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (477)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |