IfForm1.Components[i] isTCustomEdit then
withForm1.Components[i] asTCustomEdit doText:=#0;
end;
Предложенный код проверяет все расположенные на форме компоненты на принадлежность классу TCustomEdit и очищает свойство Text.
Методы класса
Метод класса – это особая категория процедур или функций, способных выполняться без создания экземпляра класса. Классический пример метода класса – уже знакомый нам конструктор. Объявление метода класса обычно начинается с ключевого слова class:
typeTMyObject = class
…
class procedureMyObjectProcedure;
end;
Инкапсуляция
Наряду с наследованием и полиморфизмом, инкапсуляция является столпом, на котором держится вся концепция ООП. Основное назначение инкапсуляции – скрывать от пользователя особенности реализации класса. Если провести параллель с окружающим нас миром, то точно так же от нас спрятаны внутренности телевизора. Снаружи расположены только необходимые органы управления, с помощью которых можно найти интересующий канал, изменить громкость и яркость. При этом телезрителя мало интересуют частота гетеродина или кадровая и строчная синхронизации. Если что-то сломалось, мы вызываем мастера. Он специалист по инкапсуляции и бесстрашно снимает заднюю стенку телевизора.
Уже интуитивно понятно, что благодаря инкапсуляции повышается надежность функционирования программного объекта, поскольку, в отличие от четырех-пяти шурупов в задней стенке телевизора, неопытный программист не сможет «выкрутить винты» из программно реализованного объекта. Но помимо повышения общей надежности объекта, инкапсуляция обеспечивает программную логику его работы, а это еще более важное звено в концепции ООП. Классическим примером использования инкапсуляции являются свойства объекта.
Области видимости
При описании класса программист имеет право определять степень доступности (видимости) его полей и методов. Это один из способов защиты наиболее критичных элементов класса от несанкционированного вмешательства. Область видимости поля (метода) класса зависит от того, в какой из четырех возможных секций оно объявлено: private, protected, publicи published.
Type
TMyObject = class
Private
... { секция частных объявлений }
Protected
... { секция защищенных объявлений }
Public
... { секция общих объявлений }
Published
... { секция опубликованных объявлений }
end;
Поля и методы, доступ к которым нежелателен, обычно размещают в секциях private и protected. Наиболее защищена секция private. К размещенным в ней полям и методам возможно обращение только из того же программного модуля, в котором описан этот класс. Секция protected несколько приоткрывает завесу секретности – находящаяся в ней информация доступна для классов-потомков.
Секция public предоставляет объявленные в ней поля и методы для общего пользования всем желающим. Секция published самая доброжелательная. Например, объявленными в ней данными умеет пользоваться Инспектор объектов. Это возможно благодаря тому, что для этой секции класса генерируется информация о времени выполнения (Runtime Type Information, RTTI). Поэтому в секции published обычно объявляют все свойства и обработчики событий объекта.
Свойства объекта
Благодаря инкапсуляции объект обладает особыми характеристиками, называемыми свойствами (property). Начинающий программист зачастую воспринимает свойство как банальную переменную, принадлежащую тому или иному объекту. В эту переменную он может помещать какие-то значения, например текст заголовка кнопки, определять геометрические размеры объекта, изменять его цвет и т. п. Сравнение свойства с переменной нельзя назвать ошибочным (хотя бы потому, что именно этого впечатления упорно добивались разработчики Delphi), но все-таки это поверхностное суждение.
На самом деле свойство – это способ доступа к полям объекта. В нем, как правило, инкапсулировано два метода: чтение и запись. Эти методы обеспечивают связь между полем объекта и соответствующим ему свойством; более того, все это делается в глубокой тайне от работающего с объектом программиста. Для большей наглядности вернемся к нашему автомобилю, описанному классом TAutomobile.
Type
TAutomobile = class
Private
fSpeed : SmallInt;
fEngine : TEngine;
…
procedureSetSpeed(value : smallint);
Published
propertySpeed : SmallInt readfSpeed writeSetSpeed;
…
end;
В первую очередь обратите внимание на наличие внутри объявления класса секций частных (private) и публичных (published) объявлений. Программисту, воспользовавшемуся нашим объектом, будут доступны только свойства и методы, объявленные в секции published, и он может даже не подозревать о существовании полей fEngine и fSpeed. Зато ему предоставлена возможность обращаться к свойству Speed, причем любые действия, связанные с попыткой изменить скорость, будут контролироваться спрятанной процедурой SetSpeed(). Устанавливая новое значение скорости (в Инспекторе объектов или непосредственно из кода приложения), начинающий программист и не подозревает, что его действия контролируются:
procedureTAutomobile.SetSpeed(value : smallint);
Begin
iffEngine.fOn=False thenShowMessage('Отключен двигатель!')
Else
if(value>=0) and(value<=300) thenfSpeed:=value
elseShowMessage('Недопустимая скорость!')
end;
Таким образом «умный» объект не даст изменить скорость при выключенном двигателе и плюс ко всему убедится, что новое значение входит в допустимый диапазон.
Наследование
Вторым столпом ООП считается наследование. Это совсем простое понятие, смысл которого в том, что при описании нового класса допустимо брать за основу его родительский класс. Таким образом достигается преемственность поколений: дочерний класс наследует все методы и свойства своего предка. Ограничений на длину цепочки наследования нет; в Delphi объявлены классы, имеющие в родословной больше десятка предков. Таким образом, самый последний в иерархии наследования класс, если так можно выразиться, – самый опытный: он вобрал все лучшее от всех своих «дедушек» и «прадедушек».
Независимо от функционального назначения объекта в роли его самого «древнего» предка выступает основа основ иерархии библиотеки визуальных компонентов Delphi – класс TObject. Кроме того, TObject – единственный класс, не имеющий предка; он, так сказать, создан с чистого листа.
Механизм наследования значительно упрощает жизнь разработчика компонентов. Благодаря наследованию отпадает необходимость описывать одни и те же характеристики для разных объектов. Вместо этого достаточно найти наиболее подходящий родительский класс и на его основе описать достойного потомка.
В нашем случае класс TAutomobile может быть превращен практически в любую разновидность транспортного средства от бульдозера до трамвая. Тем более, что золотым минимумом (двигателем и свойством, описывающим скорость) он уже обеспечен. Допустим, мы хотим создать грузовик, Tlorry, предназначенный для перевозки тяжестей, поэтому необходимо снабдить класс TLorry параметром, характеризующим количество груза.
Type
TLorry = class(TAutomobile)
fCargoCount : real;
…
propertyCargoCount : real readGetCargoCount writeSetCargoCount;
end;
Обратите внимание на особенность объявления дочернего класса. Во фрагменте кода, посвященном созданию потомка класса TAutomobile, за ключевым словом classв круглых скобках следует имя родительского класса:
TLorry = class(TAutomobile)
С этого момента, встретив подобную строку кода в любом листинге, вы сразу поймете, кто чей родственник. Если же вдруг за словом class будет пусто, то это признак того, что класс создается на основе TObject. Поэтому объявление класса:
TAutomobile = class(TObject)
эквивалентно объявлению:
TAutomobile = class
Процесс наследования допускает не только полный перенос свойств и методов от предка к потомку, при желании он вполне управляем. Мы имеем полное право спрятать ненужные свойства и методы или видоизменить их. Так что наследование – это достаточно гибкий механизм, позволяющий развивать дочерние классы.
Полиморфизм
Полиморфизм едва ли не самый сильный козырь ООП. Дословная расшифровка этого термина обозначает обладание многими формами. Идея полиморфизма тесно связана с наследованием и заключается в праве экземпляра некоторого класса представлять все классы из его иерархической цепочки.
Более того, благодаря полиморфизму мы получаем право скрывать или переопределять поведение унаследованных методов. Поэтому различные по
содержанию процедуры и функции всевозможных объектов могут использовать одно и то же имя, а вызов метода будет приводить к выполнению кода, соответствующего конкретному экземпляру объекта.
В качестве номинантов на первую премию в области полиморфизма я бы привел абстрактные классы TComponent и TDataSet (один из прямых наследников TComponent).
Класс TComponent служит базисом для разработки компонентов – всего того, что вы видите на палитре компонентов Delphi. Класс TDataSet представляет собой унифицированный, не зависящий от конкретной платформы (Paradox, dBase, Access, InterBase и т. д.) набор данных, служащий основой для построения всех компонентов доступа к базам данных.
Рассмотрим небольшой пример, демонстрирующий идеи полиморфизма.В листинге объявлено три класса: животное (TAnimal), кошка (TCat) и лев (TLion). Предположим, что в роли предка всех кошачьих выступает класс TAnimal, на его основе создан класс TCat и на вершине пирамиды наследования царствует TLion. Все три зверя снабжены одним единственным методом процедурой Run().
typeTAnimal = class
procedureRun; virtual; abstract;
end;
typeTCat = class(TAnimal)
procedureRun; override;
end;
typeTLion = class(TCat)
procedureRun; override;
end;
Implementation
procedureTCat.Run;
Begin
ShowMessage('Cat run');
end;
procedureTLion.Run;
Begin
ShowMessage('Lion run');
end;
Родоначальник всех зверей, класс TAnimal, сделан абстрактным. Это особый тип класса, который никогда не сможет превратиться в объект; в рамках этого класса программист лишь рисует наброски потенциального объекта. Основу класса составляют заголовки абстрактных (abstract) методов. Это особый вид метода, который в рамках абстрактного класса лишь объявляется и не имеет реализации. Однако наличие абстрактного метода обязывает класс-наследник описать этот метод, как это и сделано в TCat и TLion. Таким образом, абстрактный класс – это своего рода договор о намерениях, обязывающий всех своих потомков действовать по заложенной в нем идее.
Дата добавления: 2016-03-15; просмотров: 498;