Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.30;
Скачать: CL | DM;

Вниз

Вопрос про ООП   Найти похожие ветки 

 
ВаняЯ   (2007-12-06 21:42) [0]

У меня есть класс и его наследник. В коде программы в зависимости от условия нужно создавать или изначальный экземпляр класса или его наследник. Как в таком случае следует поступить? (Ну переменная должна быть одна, см. неработающий пример)
 TMyClass1 = class(...)
 private
   Timer: TTimer;
   ....
   FStr1: string;
 public
   constructor Create;  virtual;
   procedure Go1; virtual;
   property str1: string read FStr1 write FStr1;
 end;

 TMyClass2 = class(TMyClass1)
 private
   FStr2: string;
   ....
 public
   constructor Create; override;
   procedure Go1; override;
   property str2: string read FStr2 write FStr2;

 end;

------
 var
   Class: TMyClass1;
 begin
   Class := TMyCalss2.Create;
   Class.str2 := "test"; //  Error


 
Юрий Зотов ©   (2007-12-06 21:50) [1]

Нужно подсказать компилятору фактический класс переменной. Иначе он использует тот, с которым она объявлена, а в нем str2 нет.

var
  AClass: TMyClass1;
begin
  AClass := TMyClass2.Create;
  TMyClass2(AClass).str2 := "test";


 
ВаняЯ   (2007-12-06 21:53) [2]

А такая практика, как у меня в примере - нормальная, или это извращение?


 
Юрий Зотов ©   (2007-12-06 21:56) [3]

> ВаняЯ   (06.12.07 21:53) [2]

Нормальная. В VCL подобное часто используется.


 
Sergey Masloff   (2007-12-06 21:56) [4]

Юрий Зотов ©   (06.12.07 21:50) [1]
А тогда на фига весь сыр-бор? Если хочется полиморфизма то интерфес объекта должен быть одинаков в данном контексте. То есть уж либо

TMyClass1 = class(...)
private
  Timer: TTimer;
  ....
  FStr1: string;
public
  constructor Create;  virtual;
  procedure Go1; virtual;
  property str1: string read FStr1 write FStr1;
  property str2: string read DoNothing write DoNothing;
end;

либо другие альтернативные механизмы.
Вопрос естественно не тебе а автору топика ;-)


 
Юрий Зотов ©   (2007-12-06 22:01) [5]

> Sergey Masloff   (06.12.07 21:56) [4]

Аналог - TStrings и TStringList. Потомок расширяет интерфейс предка.

Обычное дело - объявляем переменную класса предка, а создаем экземпляр потомка. Если юзаем НЕрасширенный интерфейс, то делаем это напрямую (а полиморфизм сохраняется), если расширенный - приводим класс.


 
Sergey Masloff   (2007-12-06 22:17) [6]

Юрий Зотов ©   (06.12.07 22:01) [5]
Дело-то обычное только использовать нужно с осторожностью а то ведь появится класс TMyClass3 у которого нет str2 а приведение к нему сработает


program Project2;

{$APPTYPE CONSOLE}

uses
 SysUtils;

type
 TMyClass = class(TObject)
   constructor Create(); virtual;
 end;

 TMyClass2 = class(TMyClass)
   fInt : Integer;
   fInt2 : Integer;
   constructor Create(); reintroduce; override;
 end;

 TMyClass3 = class(TMyClass)
   fInt : Integer;
   constructor Create(); reintroduce; override;
 end;

var
  c : TMyClass;

{ TMyClass }

constructor TMyClass.Create;
begin

end;

{ TMyClass2 }

constructor TMyClass2.Create;
begin
 inherited;
 fInt := 1;
 fInt2 := 2;
end;

{ TMyClass3 }

constructor TMyClass3.Create;
begin
 inherited;
 fInt := 3;
end;

begin

 c := TmyClass3.Create();
 Writeln(TMyClass2(c).fint);
 Writeln(TMyClass2(c).fint2);
 Readln;
end.


Причем в этом примере ладно а в реальном приложении он почитает что-то за границами своего экземпляра.

Ты-то это знаешь, а вот знает ли это каждый?



Страницы: 1 вся ветка

Текущий архив: 2007.12.30;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.016 c
2-1197037557
Nikfel
2007-12-07 17:25
2007.12.30
Как получить список процессов с путем.


15-1196415745
data
2007-11-30 12:42
2007.12.30
Баланс между скоростью разработки и внедрения и качеством. Мнения


15-1196457288
deras
2007-12-01 00:14
2007.12.30
Вопрос стоимости сопровождения собственного ПО


15-1196430171
alll_23
2007-11-30 16:42
2007.12.30
Способ задания алгоритма


2-1196908519
Александр Семак
2007-12-06 05:35
2007.12.30
Items в TMainMenu