/
Кафедра КТиС
Порожденный класс автоматически наследует поля, методы и свойства своего родителя и может дополнять их новыми. Таким образом, принцип наследования обеспечивает поэтапное создание сложных классов и разработку собственных библиотек классов.
В класс можно включать несколько конструкторов. При создании объекта использовать любой конструктор из данного класса или родительского класса. Если в описании класса отсутствует конструктор, то при создании объекта можно использовать любой конструктор из родительского класса.
Все классы порождены от единственного родителя класса TObject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего назначения, обеспечивающие весь жизненный цикл любых объектов - от их создания до уничтожения.
Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми свойствами и передает их своим потомкам.
Полиморфизм позволяет использовать одинаковые имена для методов, входящих в различные классы. Принцип полиморфизма обеспечивает в случае обращения к одноименным методам выполнение того из них, который соответствует классу объекта.
Каждый объект обязательно описывается в разделе описания переменных. Объекты относятся к динамическим структурам данных поэтому они должны создаваться (удаляться) на этапе выполнения проекта. При создании объекта вызывается специальный метод (метод класса), называемый конструктором, После окончания работы с объектом он должен быть обязательно удален (уничтожен) методом - Free.
При создании объект получает уникальный набор полей, но общий для всех объектов данного класса набор методов и свойств.
Полиморфизм - это свойство классов решать схожие по смыслу проблемы разными способами. В рамках Object Pascal поведенческие свойства класса определяются набором входящих в него методов. Изменяя алгоритм того или иного метода в потомках класса, программист может придавать этим потомкам отсутствующие у родителя специфические свойства. Для изменения метода необходимо перекрыть его в потомке, т. е. объявить в потомке одноименный метод и реализовать в нем нужные действия. В результате в объекте-родителе и объекте-потомке будут действовать два одноименных метода, имеющих разную алгоритмическую основу и, следовательно, придающих объектам разные свойства. Это и называется полиморфизмом объектов.
Методы, определенные в классе, могут быть статическими, виртуальными, динамическими или абстрактными. Тип метода определяется механизмом перекрытия его в потомках.
Для статических методов перекрытие осуществляется компилятором. Например, метод ViewSex класса TPerson1 статически перекрывается одноименным методом класса TPerson2. По умолчанию все методы, описанные в классе, являются статическими.
Динамические и виртуальные методы отличаются от статических тем, что замещение родительских методов методами потомков происходит на этапе выполнения программы. Для объявления виртуального метода в родительском классе необходимо использовать зарезервированное слово virtual, а для объявления динамического метода - зарезервированное слово dynamic. В классе-потомке в заголовке замещающего метода должно быть указано зарезервированное слово override.
Так из описания классов TPerson2 и TPerson3 следует что, метод ViewSex класса TPerson2 является виртуальным и перекрывается одноименным методом класса TPerson3.
Различие между виртуальными и динамическими методами невелико и связано с особенностями реализации их вызовов. Можно сказать, что виртуальные методы более эффективны с точки зрения затрат времени, а динамические методы позволяют более рационально использовать оперативную память.
Абстрактными называются виртуальные или динамические методы, которые определены в классе, но не содержат никаких действий, никогда не вызываются и обязательно должны быть переопределены в классах-потомках. Объявляется абстрактный метод при помощи зарезервированного слова abstract, расположенного после слов virtual или dynamic.
Основное предназначение абстрактных методов - быть родоначальником иерархии конкретных методов в классах-потомках.
Если переопределяемый в классе-наследнике метод имеет другой список параметров, то он не скрывает, а перегружает метод наследник. Для того чтобы метод был перегружаемым, в объявлении метода вместо override. необходимо указать ключевое слово overload.
Классы могут быть описаны только в интерфейсной части модуля (как правило, это и делается) или в разделе реализации модуля, описывать классы в процедурах и функциях запрещено. Методы класса (конструкторы, процедуры и функции) должны быть обязательно описаны в разделе реализации модуля.
Все методы являются методами класса, а не объекта, поэтому при описании метода в названии используется имя класса (например, TPerson1.ViewSex ).
Конструкторы класса используются, как правило, для начальной инициализации полей, предварительно необходимо вызвать конструктор родительского класса, используя директиву inherited.
При создании объекта в памяти (куче) выделяется место под хранение данных и методов класса, а переменная просто является ссылкой на выделенную область.
Компонент в Delphi представляют класс, а компонент установленный на форму уже конкретный объект. При работе с классами - компонентами, система автоматически создает (при установке компонента на форму) и удаляет (при удалении компонента) объекты.
2. Разработка классов транспортных средств
Разработать классы и создать приложение:
Разработать класс, который инкапсулирует информацию о транспортных средствах, таких как легковые автомобили, автобусы, грузовики. Этот класс (Vehicle) должен хранить следующие данные - количество Мест (Seats), объем бака (Сap), расстояние (mpl), которое проедет автомобиль, используя один литр топлива.
В классе использовать 3 поля (FSeats, Ffuelcap, Fmpl);
Создать объект Motor.
Ввести значения полей(FSeats, FCap, Fmpl).
Найти максимальное расстояние, которое может пройти автомобиль Motor, имея полный бак.
Создать класс (Vehicle1) , который является наследником класса Vehicle, определить в нем 3 свойства Passengers (число пассажиров), Fuel (топлива в баке), Mpl, все типа Byte. Последнее свойство работает только на чтение. В процедурах записи значений свойств Passengers, Fuel использовать ограничения.
В классе Vehicle1, определить метод (MaxDistance), который определяет максимальную дальность поездки, с данной заправкой топливного бака.
Для класса Vehicle1 разработать конструктор с начальной инициализацией. При этом бак должен быть заполнен наполовину, пассажиров столько сколько мест.
Создать объект Motor1 класса Vehicle1.
Ввести значения свойств (Passengers, Fuel).
Вывести максимальную дальность поездки.
Ввести расстояние, которое должен пройти автомобиль Motor1 и найти оставшееся количество топлива.
Создать класс (Vehicle2) , который является наследником класса Vehicle1, переопределить в нем метод (MaxDistance), который определяет максимальную дальность поездки, учетом числа пассажиров (пробег авто на 1 литр бензина уменьшается на (k-1), где к - число пассажиров).
В классе Vehicle2 определить метод FuelNeeded, который на заданное расстояние возвращает необходимое количество топлива.
Создать объект Motor2 класса Vehicle2, используя конструктор класса Vehicle1.
Присвоить объекту Motor1 данные объекту Motor2.
Ввести расстояние, и определить необходимое количество топлива для автомобилей Motor1 и Motor2.
Исходный текст Delphi приложения:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
Label4: TLabel;
Button3: TButton;
SpinEdit1: TSpinEdit;
SpinEdit2: TSpinEdit;
SpinEdit3: TSpinEdit;
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TVehicle = class(TObject)
private
Fseats, Ffuelcap, Fmpl: integer;
Constructor Create1;
end;
type
TVehicle1 = class(TVehicle)
private
FPassengers, FFuel: byte;
function GetPassegers:byte;
procedure SetPassegers(N:byte);
function GetFuel:byte;
procedure SetFuel(N:byte);
function Getmpl:integer;
constructor Create2;
public
property Passengers:byte read GetPassegers write SetPassegers;
property Fuel:byte read GetFuel write SetFuel;
property mpl:integer read Getmpl;
function MaxDistance:byte; virtual;
end;
type
TVehicle2 = class(TVehicle1)
private
public
function MaxDistance:byte; override;
end;
var
Form1: TForm1;
Motor: TVehicle;
Motor1: TVehicle1;
Motor2: TVehicle2;
implementation
Constructor TVehicle.Create1;
begin
inherited Create;
Fseats:=1;
FFuelcap:=1;
Fmpl:=1;
end;
{$R *.dfm}
constructor TVehicle1.Create2;
begin
inherited Create;
Fseats:=2;
FFuelcap:=2;
Fmpl:=1;
Passengers:=Fseats;
Fuel:=FFuelcap div 2;
end;
function TVehicle1.GetPassegers:byte;
begin
Result:=FPassengers;
end;
procedure Tvehicle1.SetPassegers(N:byte);
begin
if N>Fseats then FPassengers:=N else showmessage('Число пассажиров не может быть больше числа мест');
end;
function TVehicle1.GetFuel:byte;
begin
Result:=FFuel;
end;
procedure Tvehicle1.SetFuel(N:byte);
begin
if N>Ffuelcap then FFuel:=N else showmessage('указано число превышающее вместимость бака');
end;
function TVehicle1.Getmpl:integer;
begin
Result:=Fmpl;
end;
function TVehicle1.MaxDistance: byte;
begin
Result:=Ffuel div Fmpl;
end;
function Tvehicle2.MaxDistance:byte;
begin
Result:=Ffuel div (Fmpl-(Passengers-1));
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
motor.Free;
close;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Motor:=TVehicle.Create1;
Motor.Fseats:=strtoint(spinEdit1.Text);
Motor.Ffuelcap:=strtoint(spinEdit2.Text);
Motor.Fmpl:=strtoint(spinEdit3.Text);
Label4.Caption:='Максимальное расстояние '+inttostr(Motor.Ffuelcap div Motor.Fmpl)+' км';
end;
3. Разработка структур классов (Кошки)
Исходный текст программы, содержащей классы, служащие для описания объектов типа «кошки»:
unit CatSource1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, jpeg, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
ComboBox1: TComboBox;
Edit2: TEdit;
Edit4: TEdit;
Image1: TImage;
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
GroupBox3: TGroupBox;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
Button8: TButton;
Button9: TButton;
Button10: TButton;
Button11: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button6Click(Sender: TObject);
procedure Button7Click(Sender: TObject);
procedure Button8Click(Sender: TObject);
procedure Button9Click(Sender: TObject);
procedure Button10Click(Sender: TObject);
procedure Button11Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TCats1 = class(TObject)
private
FName: string;
FSex: byte;
constructor Create1;
function GetName:string;
procedure SetName(N:string);
function GetSex:string;
procedure SetSex(S:string);
public
property Name:string read GetName write SetName;
property Sex:string read GetSex write SetSex;
function CatDescription:string;
end;
type
TCats2 = class(TCats1)
private
//FAge
FAge: byte;
Constructor Create2;
function GetAge:byte;
procedure SetAge(A:byte);
public
property Age:byte read GetAge write SetAge;
function CatDescription:string; virtual;
end;
type
TCats3 = class(TCats2)
private
//FBreed
//FColor
FColor: string;
Constructor Create3;
function GetColor:string;
procedure SetColor(C:string);
public
property Color:string read GetColor write SetColor;
function CatDescription:string; override;
end;
var
Form1: TForm1;
Cat1: TCats1;
Cat2: TCats2;
Cat3: TCats3;
LastUsedCat:byte;
implementation
{$R *.dfm}
//constructors
constructor TCats1.Create1;
begin
inherited Create;
Name:='Lucky';
Sex:='male cat';
end;
constructor TCats2.Create2;
begin
inherited Create1;
Age:=1;
end;
constructor TCats3.Create3;
begin
inherited Create2;
Color:='black';
end;
//functions and procedures for classes
//TCats1
function TCats1.GetName;
begin
Result:=FName;
end;
procedure TCats1.SetName(N:string);
begin
FName:=N;
end;
function TCats1.GetSex:string;
begin
if FSex=1 then Result:='male cat' else Result:='female cat';
end;
procedure TCats1.SetSex(S:string);
begin
if S='male cat' then FSex:=1 else if S='female cat' then Fsex:=0 else showmessage ('Пол указан неверно');
end;
function TCats1.CatDescription:string;
begin
Result:='This cat is a '+Sex+', name''s '+Name;
end;
//TCats2
function TCats2.GetAge:byte;
begin
Result:=FAge;
end;
procedure TCats2.SetAge(A:byte);
begin
FAge:=A;
end;
function TCats2.CatDescription:string;
var AgeDescription:string;
begin
if Age<3 then ageDescription:='a young' else if Age<5 then ageDescription:='a mature' else AgeDescription:='an old';
Result:='This cat is '+ageDescription+' '+Sex+', name''s '+Name;
end;
//TCats3
function TCats3.GetColor:string;
begin
Result:=FColor;
end;
procedure TCats3.SetColor(C:string);
begin
FColor:=C;
end;
function TCats3.CatDescription:string;
var AgeDescription:string;
begin
if Age<3 then ageDescription:='a young' else if Age<5 then ageDescription:='a mature' else AgeDescription:='an old';
Result:='This cat is '+ageDescription+' '+Color+' '+Sex+', name''s '+Name;
end;
//Other things like button events handlers etc.
procedure TForm1.Button1Click(Sender: TObject);
begin
Cat1.Free;
Cat2.Free;
Cat3.Free;
close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Cat1:=TCats1.Create1;
LastUsedCat:=1;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
try
Memo1.Lines.Add(Cat1.CatDescription);
except on EAccessViolation
do
showmessage('Create a cat first')
end;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
try
Edit1.Text:=Cat1.Name;
If Cat1.Sex='male cat' then ComboBox1.ItemIndex:=1 else ComboBox1.ItemIndex:=2;
except on EAccessViolation
do
showmessage('You should have a cat first')
end;
end;
procedure TForm1.Button5Click(Sender: TObject);
begin
Cat2:=TCats2.Create2;
LastUsedCat:=2;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
try
Memo1.Lines.Add(Cat2.CatDescription);
except on EAccessViolation
do
showmessage('Create a cat first')
end;
end;
procedure TForm1.Button7Click(Sender: TObject);
begin
try
Edit1.Text:=Cat2.Name;
If Cat2.Sex='male cat' then ComboBox1.ItemIndex:=1 else ComboBox1.ItemIndex:=2;
Edit2.Text:=inttostr(Cat2.Age);
except on EAccessViolation
do
showmessage('You should have a cat first')
end;
end;
procedure TForm1.Button8Click(Sender: TObject);
begin
Cat3:=TCats3.Create3;
LastUsedCat:=3;
end;
procedure TForm1.Button9Click(Sender: TObject);
begin
try
Memo1.Lines.Add(Cat3.CatDescription);
except on EAccessViolation
do
showmessage('Create a cat first')
end;
end;
procedure TForm1.Button10Click(Sender: TObject);
begin
try
Edit1.Text:=Cat3.Name;
If Cat3.Sex='male cat' then ComboBox1.ItemIndex:=1 else ComboBox1.ItemIndex:=2;
Edit2.Text:=inttostr(Cat3.Age);
Edit4.Text:=Cat3.Color;
except on EAccessViolation
do
showmessage('You should have a cat first')
end;
end;
procedure TForm1.Button11Click(Sender: TObject);
begin
if LastUsedCat = 1 then
begin
Cat1.Name:=Edit1.Text;
if ComboBox1.ItemIndex=1 then Cat1.Sex:='male cat' else Cat1.Sex:='female cat';
end
else if LastUsedCat = 2 then
begin
Cat2.Name:=Edit1.Text;
if ComboBox1.ItemIndex=1 then Cat2.Sex:='male cat' else Cat2.Sex:='female cat';
try
Cat2.Age:=strtoint(Edit2.Text);
except on EConvertError
do
showmessage('Age should have an integer value')
end;
end
else if LastUsedCat = 3 then
begin
Cat3.Name:=Edit1.Text;
if ComboBox1.ItemIndex=1 then Cat3.Sex:='male cat' else Cat3.Sex:='female cat';
try
Cat3.Age:=strtoint(Edit2.Text);
except on EConvertError
do
showmessage('Age should have an integer value')
end;
Cat3.Color:=Edit4.Text;
end
else showmessage('There is no cats here yet.');
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
LastUsedCat:=0;
end;
end.
Заключение
программирование инкапсуляция полиморфизм
Классы являются основополагающим понятием в объектно-ориентированном программировании, их необходимо уметь использовать для того, чтобы иметь право называться программистом в современном мире. Выполняя данную курсовую работу, я ознакомился с основными принципами ООП, научился описывать классы и понял, откуда должны браться эти интересные штуки сбоку от редактора текста, назначения которых раньше не осознавал. В ходе работы были созданы два небольших приложения для работы с классами: про автомобили и про котов, описанные в данной работе.
Список использованных источников
Баас, Р. Delphi 5 для пользователя. [Текст]: Издательская группа BHV 2000. - 496 с.
Епашнеков, А. Программирование в среде Delphi [Текст]: учебное пособие. В 4-х ч. Ч. 1./ под ред. А. Епашнеков, В. Епашнеков - М.: ДИАЛОГ-МИФИ, 1998. - 336с.
Фаронов, В.В. Delphi 4. Учебный курс [Текст]: / В.В. Фаронов. - М.: Нолидж 1998. - 450 с.
Фаронов, В.В. Turbo Pascal 7.0. Начальный курс. [Текст]: учебное пособие / В.В. Фаронов. - М.: Нолидж 1997. - 616 с.
Фаронов, В.В. Turbo Pascal 7.0. Практика программирования. [Текст]: учебное пособие. / В.В. Фаронов. - М.: Нолидж 1997. - 432 с.
Бобровский, С. Delphi 7. Учебный курс. [Текст]: / С. Бобровский. - Питер, 2003. - 736 стр.
Программирование и отладка в Delphi. [Текст]: учебное пособие под ред. К. Митчелл, К. Керман - Издательский дом “Вильямс” , 2003. - 672 стр.
Культин И.Б. Программирование в Turbo Pascal 7.0 и Delphi. [Текст]: Киев, BHV, 1997. - 372 стр.
Архангельский А. Я. Программирование в Delphi 7. [Текст]: ООО “Бином-Пресс”, 2005. - 1152 стр.
Гофман В. Э., Хомоненко А. Д. Delphi 6. [Текст]: ООО “БХВ-Петербург”, 2002. - 1152 стр.
Дарахвелидзе П. Г., Марков Е. П. Программирование в Delphi 7. [Текст]: ООО “БХВ-Петербург”, 2003. - 784 стр.
Кандзюба С., П. Delphi. Базы данных и приложения. [Текст]: ООО “ДиаСофтЮП”, 2005. - 576 стр.