Property B:Double read fb write SetB; 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Property B:Double read fb write SetB;



{Для установки значения property-свойства используется метод SetB, а для чтения private-свойство fb}

Property С: Double read fc;

{Для чтения property-свойства используется значение private-свойства fc}

end;

Implementation

Procedure ABC4.SetA(NewA: Double); {Описание метода SetA}

Begin

fa:= NewA;

fc:= fa * fb;

end;

Procedure ABC4.SetB(NewB: Double); {Описание метода SetB}

Begin

fb:= NewB;

fc:= fa * fb;

End;

end. {Окончание модуля}

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

Наследование

 

5.2.1. Основы наследования

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

При описании дочернего класса с использованием наследования имя родительского класса указывается в скобках после ключевого слова с1ass| в заголовке интерфейсной части описываемого класса:

Туре

<Имя класса> = class (<Имя родительского класса>) {Заголовок описания}

......... {Описание собственных свойств и методов }

End;

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

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

 

5.2.2. Переопределение методов

Часто встречается ситуация, когда один или несколько методов дочернего класса должны работать не так, как в родительском классе. В качестве примера можно привести класс TGeomFigure, представляющий собой абстрактную геометрическую фигуру, и имеющий метод Draw для ее рисования. Наследниками этого класса могли бы быть классы TCircle для работы с окружностями, TLine для работы с линиями, и так далее.

Очевидно, что все дочерние классы в такой ситуации должны изменить метод Draw, чтобы корректно отображать фигуры, которым они соответствуют. Изменение функциональности унаследованных методов в дочерних классах называется переопределением методов.

Механизм переопределения

 

Для переопределения метода, реализованного в объекте-родителе, следует:

 

♦ указать его заголовок в интерфейсной части описания дочернего класса без изменения имени, списка параметров и возвращаемого значения (если метод является функцией);

♦ указать после заголовка метода ключевое слово override. Если ключевое слово override не указано, то метод не переопределяется.

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

 

Чтобы метод мог быть переопределен в дочерних классах, он должен быть помечен ключевыми словами virtual или dynamic в интерфейсной части класса-родителя. Ключевое слово virtual указывает на то, что метод должен быть занесен в так называемую таблицу виртуальных методов ТВМ), а ключевое слово dynamic на то, что метод должен быть найден ло имени в дереве родительских объектов.

Разница между использованием virtual и dynamic заключается в направлении оптимизации компилятором вызовов переопределяемых методов. Методы, помеченные virtual, оптимизируются по скорости, а zynamic-методы по размеру программного кода. В большинстве случаев рекомендуется использование виртуальных методов, а использование динамических методов целесообразно при высоких степенях вложенности cвязей родитель-наследник.

Приведем описание класса TwoNums с двумя свойствами а и Ь, и методом GetResult, возвращающим сумму свойств. Далее, от этого класса эпишем наследника ThreeNums, имеющего уже три свойства — а, b и с, и переопределяющего метод GetResult таким образом, чтобы возвра­щать сумму не двух, а трех чисел (листинг 5.10).

Листинг 5.10. Использование переопределения

Unit Overriding 1;

Interface

Type

TwoNums = class

public                      {Заголовок класса TwoNums}

a, b: Integer;              {Описание двух свойств}

function GetResult: Integer; virtual; {Описание заголовка метода; после описания указано ключевое слово virtual, то есть этот метод может быть переопределен в дочернем классе}

End;

ThreeNums = class (TwoNums)

Public                        {Заголовок класса ThreeNums, в скобках после ключевого слова class указан класс-родитель}

с: Integer;              {Описание свойства с'. Свойства а и b

наследуются от класса-родителя TwoNums}

function GetResult: Integer; override;

{Описание заголовка метода, идентичного заголовку объекта-родителя; после описания указано ключевое слово override, указывающее на переопределение функциональности родительского метода}

End;

Implementation

function TwoNums.GetResult: Integer;

{Описание метода GetResult класса TwoNums}

Begin

Result:= a + b; {Результат функции — сумма двух свойств}

End;

function ThreeNums. GetResult: Integer; {Описание переопределенного метода

GetResult класса ThreeNums}

  Begin

Result:= a + b + c; {Результат функции — сумма трех свойств}

end;

End.

 

Переопределение методов с сохранением функциональности

 

В приведенном примере метод GetResult класса TwoNums полностью переопределен в классе ThreeNums, то есть его изначальная функциональность полностью утеряна, но включена в функциональность замещающего метода с помощью копирования. Это практически всегда возможно, если разработчик класса имеет доступ к исходному тексту класса-родителя, но не всегда удобно, так как программный код, реализующий метод, может иметь немалые размеры.

Для сохранения функциональности переопределенного метода в Delphi имеется возможность его вызова из переопределяющего метода с помощью ключевого слова inherited, используемого следующим образом:

Inherited  <Название метода>(<список параметров>);

Аналогично могут вызываться и переопределенные методы, которые являютсяфункциями:

….:= Inherited <Название метода>(<Список параметров>);

Изменим предыдущий пример таким образом, чтобы сумма свойств в методе GetResult вычислялась с использованием переопределенного вариантаэтого метода, описанного в классе TwoNums (листинг 5.11).

 

Листинг 5.11. Переопределение методов с сохранением функциональности

Unit  0verriding2;

Interface

Type

TwoNums = class

 public

a, b: Integer;

function GetResult: Integer; virtual;

 End;

ThreeNums = class (TwoNums)

 public

 c: Integer;

 function GetResult: Integer; override;

 End;

Implementation



Поделиться:


Последнее изменение этой страницы: 2021-04-04; просмотров: 51; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.129.19.251 (0.014 с.)