2

私は商用コンポーネントスイートから派生したコンポーネントに取り組んでおり、これまで考えたことのない課題に直面しました。次のコードスニペットについて考えてみます。

TMyClass = class
protected
  procedure SomeMethod; virtual;
end;

TMyClass1 = class(TMyClass)
protected
  procedure SomeMethod; override;
end;

TMyMode = (mmOne, mmTwo);
TMyClass2 = class(TMyClass1)
private
  FMode: TMyMode;
protected
  procedure SomeMethod; override;
public
  property Mode: TMyMode read FMode write FMode;
end;

...

procedure TMyClass2.SomeMethod;
begin
  if FMode = mmOne then inherited SomeMethod
                   else inherited TMyClass.SomeMethod;
end;

したがって、Mode = mmOneの場合、通常どおり継承しますが、mmTwoの場合でも、祖先の祖先からコードを継承しますが、祖先に導入されたコードは継承しません。私は上記を試しましたが、成功しませんでしたが、これまでに遭遇したことがないので、不可能だと思います。テイカーはいますか?

4

2 に答える 2

6

これは、クラスヘルパーを使用して行うことができます。

type
  TA = class
  public
    procedure X; virtual;
  end;

  TB = class(TA)
  public
    procedure X; override;
  end;

  TA_Helper = class helper for TA
    procedure A_X;
  end;

  TC = class(TB)
  public
    procedure X; override;
  end;

procedure TA.X;
begin
  // ...
end;

procedure TB.X;
begin
  // ...
end;

procedure TA_Helper.A_X;
begin
  inherited X; // TA.X
end;

procedure TC.X;
begin
  A_X;
  inherited X; // TB.X
end;

クラスヘルパーはD2006に存在すると思いますが、存在しない場合は、ハックを使用して同じ効果を得ることができます。

// ...
  TA_Helper = class(TA)
    procedure A_X;
  end;
// ...
procedure TC.X;
begin
  TA_Helper(Self).A_X;
  inherited X; // TB.X
end;
于 2012-05-30T11:19:02.670 に答える
4

クラスヘルパーや追加のメソッドを使用しないこのタスクの別の解決策があります(@hvdanswerのように)。基本クラスのメソッドのコードアドレスを取得し、selfData-pointerで呼び出すことができます:
rttiなしで更新されたコード

unit Unit4;

interface
type
    TA = class(TObject)
      protected
        procedure Test(); virtual;
    end;

    TB = class(TA)
      protected
        procedure Test(); override;
    end;

    TC = class(TB)
      public
        procedure Test(); override;
    end;

implementation

procedure TA.Test;
begin
    writeln('TA.Test()');
end;

procedure TB.Test;
begin
    writeln('TB.Test');
end;

procedure TC.Test;
var TATest : procedure of object;
begin
    writeln('TC.Test();');
    writeln('call inherited TB: ');
    inherited Test();


    writeln('call inherited TA:');
    TMethod(TATest).Data := self;
    TMethod(TATest).Code := @TA.Test;
    TATest();
end;
end.
于 2012-05-30T13:44:03.753 に答える