Delphi. Урок 24. Приведение типов 2.2
Нисходящие приведения наоборот позволяют преобразовать объект, изначально представленный в виде экземпляра родительского класса, к виду дочернего класса.
[tip]Кстати говоря, абсолютно все классы в Delphi являются в конечном счете дочерними для класса TObject. Это позволяет представить или описывать любой объект как экземпляр класса TObject. Но с этим следует быть осторожным, чтобы не допустить неправильных приведений.[/tip]
В случае с нашим примером, можно реализовать следующее

 
1

2

3

4

5

6

7

8
 
var 

  o : TParent;

begin

  o := TChild.Create;

  (as TChild).ChildMethod; 

// Имея объект, изначально представленный экземпляром родительского класса,

// при помощи оператора "as", мы обращаемся к методу дочернего класса.

end;

Если бы объект «o» был изначально создан как TParent, т.е. так:

1

2

3

4

5

6
 
var

  o : TParent;

begin

  o := TParent.Create;

  (as TChild).ChildMethod; // Ошибка "Invalid class typecast"

end;

то во время работы программы (в run-time) мы бы получили ошибку «Invalid class typecast», т.к. на самом деле не каждый экземпляр класса TParent может являться еще и экземпляром класса TChild!
Ну и как уже было упомянуто, можно использовать и самый базовый класс TObject, чтобы описывать при помощи него (потенциально) экземпляр любого другого класса, т.к. любой другой класс является дочерним для TObject. Главное не совершить ошибку из предыдущего примера! Тоже приведем пример:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17
 
var

  a: array [1..3] of TObject;

begin

  a[1] := TParent.Create; 

  // К объекту a[1] можно будет обратиться как к объекту класса 

  // TParent при помощи нисходящего приведения типов

  a[2] := TChild.Create;

  // К объекту a[2] можно будет обратиться как к объекту класса 

  // TChild при помощи нисходящего приведения типов

  a[3] := TButton.Create(Form1);

  // Можно даже создать кнопку =)

  (a[3] as TButton).Parent := Form1;

  // И обращаться к ее методам, полям и свойствам

  (a[3] as TButton).Left := 100;

  (a[3] as TButton).Top := 100;

  (a[3] as TButton).Caption := 'My button';

end;

На самом деле код с присвоением свойств для кнопки можно было оптимизировать так:

1

2

3

4

5

6

7
 
with a[3] as TButton do

begin

  Parent := Form1;

  Left := 100;

  Top := 100;

  Caption := 'My button';

end;

Ключевое слово with позволяет временно установить приоритет для полей, методов или свойств указанного после объекта.
Ну и напоследок хотелось бы еще сказать пару слов об операторе is, который позволяет сравнить класс объекта с каким-либо другим классом. Вот еще небольшое дополнение для последнего примера, которое как раз и демонстрирует использование is:

 
1

2

3

4

5

6

7

8
 
if a[3] is TButton then

begin

  ShowMessage('a[3] - это кнопка. Ее можно переименовать!');

  (a[3] as TButton).Caption := 'New name for button';

end;

if a[2] is TParent then

  ShowMessage('a[2] является TParent'); 

// Условие выполнится, т.к. всякий TChild может быть преобразован к TParent.

Таким образом, конструкция

 
1
 
(Object is TClass)

возвращает значение Boolean. True — если объект является экземпляром класса TClass, False — в противном случае.

Категория: delphi 7 | Добавил: ghost_mod (14.09.2016)
Просмотров: 436 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email:
Подписка:1
Код *: