Студопедия

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника



Примечание. Прекрасный пример, иллюстрирующий наследование, представляет собой иерархия классов VCL.




Читайте также:
  1. Примечание
  2. Примечание
  3. Примечание
  4. Примечание
  5. Примечание
  6. Примечание
  7. Примечание
  8. Примечание
  9. Примечание
  10. Примечание

Прекрасный пример, иллюстрирующий наследование, представляет собой иерархия классов VCL.

В Object Pascal все классы являются потомками класса TObject. Поэтому, если вы создаете дочерний класс прямо от TObject, то в определении его можно не упоминать. Следующие два выражения одинаково верны:

TMyObject = class(TObject); TMyObject = class;

Первый вариант, хотя он и более длинный, предпочтительнее — для устранения возможных неоднозначностей. Класс TObject несет очень серьезную нагрузку и будет рассмотрен отдельно.

Унаследованные от класса-предка поля и методы доступны в дочернем классе; если имеет место совпадение имен методов, то говорят, что они перекрываются.

Поведение методов при наследовании, без преувеличения, является краеугольным камнем объектно-ориентированного программирования. В зависимости от того, какие действия происходят при вызове, методы делятся на три группы. В первую группу отнесем статические методы, во вторую — виртуальные (virtual) и динамические (dynamic) и, наконец, в третью — появившиеся только в Delphi 4 — перегружаемые (overload) методы.

Методы первой группы полностью перекрываются в классах-потомках при их переопределении. При этом можно полностью изменить объявление метода. Методы второй группы при наследовании должны сохранять наименование и тип. Перегружаемые методы дополняют механизм наследования возможностью использовать нужный вариант метода (собственный или родительский) в зависимости от условий применения. Подробно все эти методы обсуждаются ниже.

Язык C++ допускает так называемое множественное наследование. В этом случае новый класс может наследовать часть своих элементов от одного родительского класса, а часть — от другого. Это, наряду с удобствами, зачастую приводит к проблемам. В Object Pascal понятие множественного наследования отсутствует. Если вы хотите, чтобы новый класс объединял свойства нескольких, породите классы-предки один от другого или включите в один класс несколько полей, соответствующих другим желаемым классам.

 

Полиморфизм

Рассмотрим внимательно следующий пример. Пусть у нас имеются некое обобщенное поле для хранения данных — класс TFieid и три его потомка — для хранения строк, целых и вещественных чисел:



type

TField = class

function GetData:string; virtual; abstract;

end;

TStringFieid = class(TField)

FData : string;

function GetData: string; override;

end;

TIntegerField = class(TField)

FData : Integer;

function GetData: string;override;

end;

TExtendedField = class(TField)

FData : Extended;

function GetData: string;override;

end;

function TStringFieid.GetData;

begin

Result := FData

end;

function TIntegerField.GetData;

begin

Result := IntToStr(FData);

end;

function TExtendedField.GetData;

begin

Result:= FloatToStrF(FData, ffFixed, 7, 2);

end ;

procedure ShowData(AField : TField);

begin

Forml.Label!.Caption := AField.GetData;

end;

В этом примере классы содержат разнотипные поля данных FData и только-то и "умеют", что сообщить о значении этих данных текстовой строкой (при помощи метода GetData). Внешняя по отношению к ним процедура ShowData получает объект в виде параметра и показывает эту строку.

Правила контроля соответствия типов (typecasting) языка Object Pascal гласят, что объекту как указателю на экземпляр объектного типа может быть

присвоен адрес любого экземпляра любого из дочерних типов. В процедуре showData параметр описан как TFieid — это значит, что в нее можно передавать объекты классов и TStringField,и TIntegerField, и TExtendedField,и любого другого потомка класса TFieid.



Но какой (точнее, чей) метод GetData при этом будет вызван? Тот, который соответствует классу фактически переданного объекта. Этот принцип называется полиморфизмом, и он, пожалуй, представляет собой наиболее важный козырь ООП.

Допустим, вы имеете дело с некоторой совокупностью явлений или процессов. Чтобы смоделировать их средствами ООП, нужно выделить их самые общие, типовые черты. Те из них, которые не изменяют своего содержания, должны быть реализованы в виде статических методов. Те же, которые изменяются при переходе от общего к частному, лучше облечь в форму виртуальных методов.

Основные, "родовые" черты (методы) нужно описать в классе-предке и затем перекрывать их в классах-потомках. В нашем примере программисту, пишущему процедуру вроде showData, важно лишь, что любой объект, переданный в нее, является потомком TFieid и он умеет сообщить о значении своих данных (выполнив метод GetData). Если, к примеру, такую процедуру скомпилировать и поместить в динамическую библиотеку, то эту библиотеку можно будет раз и навсегда использовать без изменений, хотя будут появляться и новые, неизвестные в момент ее создания классы-потомки TFieid.

Наглядный пример использования полиморфизма дает среда Delphi. В ней имеется класс TComponent, на уровне которого сосредоточены определенные "правила" взаимодействия компонентов со средой разработки и с другими компонентами. Следуя этим правилам, можно порождать от класса TComponent свои компоненты, настраивая Delphi на решение специальных задач.



Теперь, надеемся, стало более или менее ясно, какие преимущества ООП позволили ему стать основным способом разработки серьезного программного обеспечения. Те, кто начинал программировать еще для Windows 3.0, наверняка помнят, сколько усилий требовалось при написании совершенно тривиального кода. Сейчас для того же самого в Delphi достаточно буквально пары щелчков мышью. На самом деле именно сложность программирования для Windows стала катализатором внедрения ООП.

Методы

Из предыдущего материала читатели узнали, что функционирование объектов обеспечивается различными типами методов, которые различаются особенностями реализации механизма наследования. Теперь настало время рассмотреть эти методы более подробно.

Абстрактными называются методы, которые определены в классе, но не содержат никаких действий, никогда не вызываются и обязательно должны быть переопределены в потомках класса. Абстрактными могут быть только виртуальные и динамические методы. В Object Pascal такие методы объявляются с помощью одноименной директивы. Она указывается при описании метода:

procedure NeverCallMe; virtual; abstract;

При этом никакого кода для этого метода писать не нужно. Вызов метода NeverCallMe приведет к созданию исключительнойситуации EAbstractError (исключительным ситуациям посвящена гл. 4).

Пример с классом TField из разд. "Полиморфизм" этой главы поясняет, для чего нужно использование абстрактных методов. В данном случае класс TField не используется сам по себе; его основное предназначение — быть родоначальником иерархии конкретных классов -"полей" и дать возможность абстрагироваться от частностей. Хотя параметр процедуры showData и описан как TField, но, если передать в нее объект этого класса, произойдет исключительная ситуация вызова абстрактного метода.

Статические методы, а также любые поля в объектах-потомках ведут себя одинаково: вы можете без ограничений перекрывать старые имена и при этом изменять тип методов. Код нового статического метода полностью перекрывает (заменяет собой) код старого метода:

type

TlstObj = class

i : Extended;

procedure SetData(AValue: Extended);

end;

T2ndObj = class (TlstObj)

i : Integer;

procedure SetData(AValue: Integer);

end;

procedure TlstObj.SetData;

begin

i := 1.0;

end;

procedure T2ndObj.SetData;

begin

i := 1;

inherited SetData (0.99);

end;

В этом примере разные методы с именем SetData присваивают значения разным полям с именем i. Перекрытое (одноименное) поле предка недоступно в потомке; поэтому, конечно, два одноименных поля с именем i — это нонсенс; так сделано только для примера.


Дата добавления: 2014-12-03; просмотров: 4; Нарушение авторских прав







lektsii.com - Лекции.Ком - 2014-2021 год. (0.013 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты