Delphi. Урок 23. Свойства 2.2

С названием свойства и типов данных все понятно — на их месте мы напишем Perimeter и double соответственно. А вот про Getter и Setter нужно поговорить немного подробнее.
[note]Getter — Название метода (обязательно функция) или поля данного класса, которое будет возвращать значение при попытке получить значение от данного property. В случае использования метода — значение будет возвращаться методом-функцией, в случае поля — значение будет доставаться из поля. Используемый метод или поле должны обязательно существовать в классе, иметь описание и реализацию. Тип возвращаемый методом или полем должен обязательно соответствовать типу, указанному в объявлении property в классе.
В случае с реализацией метода в качестве Getter`а появляется возможность каким-то образом модифицировать возвращаемые данные, производить дополнительную обработку или совершить какие-либо изменения в самом экземпляре объекта, т.к. Getter в этом случае — это обыкновенный метод. Главное, чтобы он возвращал значение, как и обычная процедура.[/note]
[note]Setter — Название метода-процедуры данного класса, которая будет устанавливать значение, переданное ей в качестве единственного параметра Value, в какое-либо существующее поле. Само присвоение может быть реализовано любым образом, оно описывается в этом методе по усмотрению программиста. А сам метод должен обязательно содержать единственный параметр с именем Value и с типом, который соответствует типу property. Setter позволяет, например, предварительно преобразовать данные, прежде чем их куда-то присваивать, хотя их даже присваивать куда-то необязательно. Все зависит от цели использования property. Возможно setter просто производит какие-то взаимодействия с полями класса, и эти взаимодействия как-то зависят от переданных в property данных.[/note]
Наверное, вы уже догадались, для чего мы реализовывали методы TTriangle.GetPerimeter и TTriangle.SetPerimeter, потому что они являются самыми классическими примерами Getter`а и Setter`а. Метод GetPerimeter отвечает за возврат значения периметра во внешний код при обращении, а SetPerimeter устанавливает периметр треугольника, имея при этом параметр Value, поделенное на три значение которого затем присваивает сторонам треугольника. Посмотрим, как же будет выглядеть наше свойство (property):

1

2

3

4

5

6

7

8

9

10

11

12

13
 
TTriangle = class

private

  function GetPerimeter: double;

  procedure SetPerimeter(Value: double);

public

  a, b, c: double;

  

  property Perimeter: double read GetPerimeter write SetPerimeter;



  function Square: double;



  constructor Create(NewA, NewB, NewC: double);

end;

Вот и все, наш property успешно создан!
[important]Прошу обратить внимание на то, что свойства объявляются после объявления полей и перед объявлением методов! И да, почему же наши методы GetPerimeter и SetPerimeter, являющиеся Getter`ом и Setter`ом для свойства Perimeter, мы поместили в область доступа private? А затем, что теперь доступ нам к этим методам из внешнего кода не понадобится, их функциональные возможности теперь можно использовать посредством свойства Perimeter. Их можно и даже нужно скрыть. А нужно их скрыть еще и потому, что при объявлении свойства требуется, чтобы используемые при этом поля и методы были объявлены ранее. А т.к. методы нельзя объявлять перед property (они объявляются после всех property), то удобнее будет поместить группу доступа private выше группы доступа public. Хотя этот побочный эффект можно обойти, но в нашем случае этого делать не нужно.[/important]
Рассмотрим простой пример работы с новым классом и нашим первым свойством:

1

2

3

4

5

6

7

8

9

10
 
procedure TForm1.FormCreate(Sender: TObject);

var 

  t: TTriangle;

begin

  t := TTriangle.Create(10, 11, 12);

  t.Perimeter := 30; // Присваиваем периметр посредством property. 

  // Соответственно будет выполнен Setter (SetPerimeter) и присвоено значение сторонам треугольника

  ShowMessage('Стороны треугольника: '+FloatToStr(t.a)+';'+FloatToStr(t.b)+';'+FloatToStr(t.c)+' Периметр: '+FloatToStr(t.Perimeter));

  // Здесь мы опять обращаемся к property Perimeter, это свойство вызывает Getter GetPerimeter, которое и возвращает нам значение

end;
 

perimeterdemo (1)

 
Хотелось бы немного заострить внимание на том, что в качестве Getter`а может выступать и поле (которое тоже помещено в private). В этом случае при обращении к значению свойства будет возвращено значение этого поля. При этом Setter может, например устанавливать значение в это скрытое поле, предварительно его обработав, к примеру, если в Setter предусмотрена передача значения в сантиметрах, а поле Getter хранит в себе значение в метрах. Т.е. потребуется сначала провести в Setter`е тривиальное преобразование.
[tip]В описании свойства можно, например, не указывать Getter или Setter. Тогда мы получим в результате свойство, доступное только для записи или чтения соответственно. Выглядеть описания тогда будут так:
1

2
 
property Perimeter: double read GetPerimeter; // Возможно только чтение из property

property Perimeter: double write SetPerimeter; // Возможно только присвоение в property

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



Категория: delphi 7 | Добавил: ghost_mod (14.09.2016)
Просмотров: 439 | Комментарии: 1 | Рейтинг: 0.0/0
Всего комментариев: 1
С нами дней
28.09.2016 #1

Написал: ghost_mod

angry
Имя *:
Email:
Подписка:1
Код *: