掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
警告をなくすには? (ID:21282)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
補足 >reintroduce; は、上位クラスから呼ばれなくなりますので注意してください。 上位クラスは、上位クラスの段階で実装されたメソッドを呼び出します。 interface type TClassA = class private FTestValue: integer; protected function GetValue: integer; virtual; procedure SetValue(const Value: integer); virtual; public constructor Create; property TestValue: integer read GetValue write SetValue; end; TClassB = class( TClassA) protected procedure SetValue(const Value: integer); override; end; TClassC = class( TClassA) protected procedure SetValue(const Value: integer); reintroduce; end; TForm1省略 implementation { TClassA } constructor TClassA.Create; begin SetValue( 1); end; function TClassA.GetValue: integer; begin Result:= FTestValue; end; procedure TClassA.SetValue(const Value: integer); begin FTestValue:= Value; end; { TClassB } procedure TClassB.SetValue(const Value: integer); begin inherited SetValue( Value+1); //1足しますが overrideされています。 end; { TClassC } procedure TClassC.SetValue(const Value: integer); begin inherited SetValue( Value+1); //1足しますが、reintroduceされています。 end; //テスト procedure TForm1.Button1Click(Sender: TObject); begin with TClassA.Create do try Memo1.Lines.Add( 'CLASS-A '+IntTOStr(TestValue)); finally Free; end; with TClassB.Create do try Memo1.Lines.Add( 'CLASS-A OVERRIDE '+IntTOStr(TestValue)); finally Free; end; with TClassC.Create do try Memo1.Lines.Add( 'CLASS-A REINTRODUCE '+IntTOStr(TestValue)); finally Free; end; end; 結果、 CLASS-A 1 CLASS-A OVERRIDE 2 CLASS-A REINTRODUCE 1 となり、 CLASS-A REINTRODUCEは、上位クラスからは呼ばれていないのが確認できます。 したがって reintroduceができるのは、 ・上位クラスがそのメソッドを内部から呼んでいない ・上位クラスがそのメソッドを内部から呼んでいても問題ない 場合に限られます。 ちなみに、TCustomPanelの Create は reintroduceを使っても、問題ありません。 しかし、 type ClassAClasses = class of TClassA; などとして TClassC = class( TClassA) protected constructor Create; reintroduce; //追加 procedure SetValue(const Value: integer); reintroduce; end; のように変更。 implementation constructor TClassC.Create; begin inherited; SetValue( 100); end; //テスト procedure TForm1.Button2Click(Sender: TObject); function CreateClass( SomeClass: ClassAClasses):TClassA; begin Result:= SomeClass.Create; end; begin with CreateClass(TClassA) do try Memo1.Lines.Add( 'CLASS-A '+IntTOStr(TestValue)); finally Free; end; with CreateClass(TClassB) do try Memo1.Lines.Add( 'CLASS-A OVERRIDE '+IntTOStr(TestValue)); finally Free; end; with CreateClass(TClassC) do try Memo1.Lines.Add( 'CLASS-A REINTRODUCE '+IntTOStr(TestValue)); finally Free; end; end; 結果、 CLASS-A 1 CLASS-A OVERRIDE 2 CLASS-A REINTRODUCE 1 となり、TClassCのコンストラクタが呼ばれません。 Class of hoehoe 等を使って動的にクラスを生成したりする場合には、 reintroduceのコンストラクタが 呼び出されないということを 覚えておく必要があると思います。 機転を利かせ、動的にクラスが変化する機構を実装した場合などには バグになるので注意が必要です(はまります)
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.