Родительский класс внутри другого класса - PullRequest
3 голосов
/ 24 сентября 2010

Хорошо, у меня есть этот класс, скажем, CMain, который содержит класс CFruit. Я хотел бы запустить функции, основанные на типе CFruit (если это CPear или CApple и т. Д.). Поэтому я хотел бы сделать что-то вроде этого:

type CMain = class
   myFruit : CFruit;
   function GetFruit() : CFruit;
   procedure SetFruit( Fruit : CFruit ); 
end;

procedure CMain.SetFruit( Fruit : CFruit );
begin
  if Fruit.IsPear then .. else etc;
end;

... очевидно, компилятор мешает мне сделать это, потому что CFruit - просто CPear и родительский элемент CApple. Есть ли способ сделать это? (о создании отдельных CMain не может быть и речи). Спасибо.

Ответы [ 3 ]

7 голосов
/ 24 сентября 2010

IIUC, вы хотите виртуальные методы .

3 голосов
/ 25 сентября 2010

На самом деле есть оператор "is", который проверяет, является ли Object экземпляром класса или его предками. Это называется «динамическая проверка типов» и является расширенным. Проверьте помощь для уточнения.

В зависимости от ваших потребностей «виртуальные методы» могут быть тем, что вам нужно, как объяснили другие. Пожалуйста, проверьте правильность пути ООП, опубликованную о «виртуальных методах».

В приведенном ниже примере

if AFruit is TApple then

и

if AFruit is TFruit then

оба возвращают истину

type
  TFruit = class
  protected
    FName: string;
  public
    property Name: string read FName;
  end;

  TApple = class(TFruit)
  public
    constructor Create;
  end;

  TPear = class(TFruit)
  public
    constructor Create;
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    mixed: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FMixValue: string;
    procedure MixFruits(AFruit: TFruit);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  APear: TPear;
  AApple : TApple;
begin
  APear := TPear.Create;
  AApple := TApple.Create;
  MixFruits(APear);
  MixFruits(AApple);
  mixed.Caption := FMixValue;
end;

{ TPear }

constructor TPear.Create;
begin
  inherited;
  FName := 'Pear';
end;

{ TApple }

constructor TApple.Create;
begin
  inherited;
  FName := 'Apple';
end;

procedure TForm1.MixFruits(AFruit: TFruit);
begin
  FMixValue := FMixValue + ' ' + AFruit.Name;
  if AFruit is TApple then
    ShowMessage('An Apple')
  else if AFruit is TPear then
    ShowMessage('A Pear')
  else
    ShowMessage('What is it?');
end;
1 голос
/ 25 сентября 2010

Вот пример использования виртуальных методов:

type 
TFruit = class
public
  procedure doSomethingFruitSpecific; virtual; abstract;
end;

TPear = class(TFruit)
public
  procedure doSomethingFruitSpecific; override;
end;

TApple = class(TFruit)
public
  procedure doSomethingFruitSpecific; override;
end;

TMain = class
   procedure SetFruit( Fruit : TFruit ); 
end;

implementation

procedure TMain.SetFruit( Fruit : TFruit );
begin
  Fruit.doSomethingFruitSpecific;
end;

procedure TApple.doSomethingFruitSpecific;
begin
  Writeln('bake an apple pie');
end;

procedure TPear.doSomethingFruitSpecific;
begin
  Writeln('pick some pears');
end;
...