親子孫継承したメソッド

解決


ごろり  2021-06-14 09:52:51  No: 149711

delphi初心者です。

クラス親⇒クラス子⇒クラス孫のように継承しています。

それぞれ、メソッドAが存在しています。
クラス孫の中でメソッドA内でinheritedを行うと、クラス子のメソッドAが動きますが、それをクラス親のメソッドAをコールしたい場合はどのようにしたらよいのでしょうか?
クラス子のメソッドAは動かしたくありません。


HFUKUSHI  2021-06-14 10:31:45  No: 149713

技術的には直接それを可能にする方法はありません。
ところで"クラス孫"と"クラス子"は本当に継承関係にあるのが正しいのでしょうか?
"クラス孫"で"メソッドA"を呼び出したときに、"クラス子"の"メソッドA"の動作をさせたくないのだとすると、その継承関係は正しく分析できていない可能性があります。

それはともかく、回避策としては、"クラス親"の"メソッドA"の内容を、protectedなメソッドに移し、必要に応じてそれを呼ぶようにする、という感じでしょうか。

type
  TFooX = class(TObject)
  protected
    procedure DoA;
  public
    procedure ProcA; virtual;
  end;

  TFooXX = class(TObject)
  public
    procedure ProcA; override;
  end;

  TFooXXX = class(TObject)
  public
    procedure ProcA; override;
  end;

procedure TFooX.DoA;
begin
  { もともとProcAでやっていた動作 }
end;

procedure TFooX.ProcA;
begin
  DoA;
end;

procedure TFooXX.ProcA;
begin
  inherited;
  { 他に何かをする }
end;

procedure TFooXXX.ProcA;
begin
  DoA;
  { TFooXX.ProcAとは別の何かをする }
end;


take  2021-06-14 10:47:09  No: 149714

回答がかぶったかも
親子孫の関係において孫が親や子の要素は継承したいけど
そこで処理されていることは無視したいというのは無理です。

よく継承される代入メソッドAssignを操作すると意味がわかります。

下記に
TOya TKo TMagoは正当後継者として書いたときのそれぞれのフィールド値の処理はこうなります。

TKoのAssignはTKoクラスが持つフィールドを代入しますが
これを無視してTOyaの代入Assignメソッドだけ呼ぶのはおかしいことですね
カプセル化されている意味が無くなるかと

どうしてもそういう処理がしたいというのであれば
親クラスからの継承クラスとして定義して子クラスが持つ処理を全て実装する必要があります。

type
  TOya = class(TPersistent)
  private
    { Private 宣言 }
  FOyaData : Integer
  public
    { Public 宣言 }
    procedure Assign(Source : TPersistent);virtual;
  property OyaData : Integer read FOyaData write FOyaData
  end;

type
  TKo = class(TOya)
  private
    { Private 宣言 }
  FKoData : Integer
  public
    { Public 宣言 }
    procedure Assign(Source : TPersistent);oveeride;
  property KoData : Integer read FKoData write FKoData
  end;

type
  TMago = class(TKo)
  private
    { Private 宣言 }
  FMagoData : Integer
  public
    { Public 宣言 }
    procedure Assign(Source : TPersistent);oveeride;
  property MagoData : Integer read FMagoData write FMagoData
  end;

type
  TMago2 = class(TOya)
  private
    { Private 宣言 }
  FKoData : Integer
  FMagoData : Integer
  public
    { Public 宣言 }
    procedure Assign(Source : TPersistent);oveeride;
  property KoData : Integer read FKoData write FKoData
  property MagoData : Integer read FMagoData write FMagoData
  end;

procedure TOya.Assgin(Source: TPersistent);
var
  a : TOya;
begin
  if Source is TOya then begin
    a := TOya(Source);
    FOyaData := a.FOyaData;
  end
  else begin
    inherited;
  end;
end;

procedure TKo.Assgin(Source: TPersistent);
var
  a : TKo;
begin
  if Source is TKo then begin
    a := TKo(Source);
    FKoData := a.FKoData;
    inheried;
  end
  else begin
    inherited;
  end;
end;

procedure TMgo.Assgin(Source: TPersistent);
var
  a : TMago;
begin
  if Source is TMago then begin
    a := TMago(Source);
    FMagoData := a.FMagoData;
    inheried;
  end
  else begin
    inherited;
  end;
end;

procedure TMago2.Assgin(Source: TPersistent);
var
  a : TMago2;
begin
  if Source is TMago2 then begin
    a := TMago2(Source);
    FKoData := a.FKoData + 1;
    FMagoData := a.FMagoData;
    inheried;
  end
  else begin
    inherited;
  end;
end;


ごろり  2021-06-14 11:02:41  No: 149715

HFUKUSHI さん
takeさん

返信ありがとうございます。
無理だという事がわかりました。

回答頂いたソースを参考に、再考してみます。
ありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加