Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];

Вниз

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

 
ВаняЯ   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.006 c
15-1196169956
de.
2007-11-27 16:25
2007.12.30
Компоненты


2-1196808279
mr1Andersen
2007-12-05 01:44
2007.12.30
Как программно в компоненте ListBox выделить строчку(элемент)


2-1196757033
DeBUGger13
2007-12-04 11:30
2007.12.30
Получить обработчик события OnClick TButton a


15-1196333240
fleg
2007-11-29 13:47
2007.12.30
Books


15-1196462270
Petr V. Abramov
2007-12-01 01:37
2007.12.30
.Net 2-й fw





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский