掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
inheriteの使い方は? (ID:20375)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
#inherited inherited は、ご先祖様のメソッドやプロパティにアクセスするだけです。 これ以外の何者でもありません。理解に苦しんでいるなら、 この言葉そのままの意味で受け取ってください。 忘れ去られがちですが 異なる名前のメンバーにもアクセスできます。 type TClassB=class(TClassA) procedure ProcA; override; end; procedure TClassB.ProcB; begin inherited ProcA; end; いっぱいあったって別にかまいません。 procedure TClassB.ProcB; begin inherited ProcA; inherited ProcB; inherited ProcC('hoe',1,2); end; 他にも returnも返せます。 Result:= inherited Something; 代入もできます。 inherited Test:=ABC; 論理式中にも使えます。 if (not (inherited Enabled)) and (inherited Text='') then Raise Exception.Create('hoe'); よくみる inherited; なるシンプルな記述は、 それが記述してある関数または手続きと同じ名前、パラメータで呼び出すという事です。 #override inheritedを語るには、overrideも語らなくてはなりません…。 override したメソッドは 新しく実装した部分が、そのクラスにのみ影響する のではなく、上位クラス(TObject方面)が、そのメソッドを内部で呼び出している 場合にも、影響します。 (ご先祖様にも影響するということです。) overrideしていなくても、inheritedは、呼び出すことができます。 overrideしてないメソッドは、 上位クラスからは通常、アクセスできず、上位クラスで実装されている段階の 処理内容が実行されます。(ご先祖様は影響を受けません。) 例えば、TButton.Click; などは、内部でも(ご先祖様も) Clickを呼び出しています。(マウスボタンがあがった時) なので、Click を override して uses ....StdCtrls; type TMyButton=class(TButton) procedure Click; override; // O V E R R I D E end; implementation procedure TMyButton.Click; begin inherited Click; MessageBeep(MB_OK); end; procedure TForm1.OnCreate( Sender: TObject); begin with TMyButton.Create(Self) do begin Parent:=Self; //Click; //後述で使います //OnClick:=ClickHandler;//後述で使います end; end; procedure TForm1.ClickHandler(Sender: TObject); begin //後述で使います //MessageDlg('ほえ?',mtInformation,[mbOK],0); end; などとすれば、 クリックするたびに音がなります。 に対して override をつけない場合には、 Clickを呼び出すコードを書かない限り、音はなりません。 例えば procedure TForm1.OnCreate( Sender: TObject); begin with TMyButton.Create(Self) do begin Parent:=Self; Click; // この瞬間 OnClick:=ClickHandler; Left:= (Self.ClientWidth - Width ) div 2; Top := (Self.ClientHeight- Height) div 2; end; end; この瞬間以外、音はなりません。 ちなみに override しても inherited しないと、クリックしても OnClickイベントが発生しなくなります。 procedure TMyButton.Click; begin // inherited Click; // C O M M E N T O U T MessageBeep(MB_OK); end; (注: Clickをoverride してください) #virtual 上位クラスで virtualかdynamic じゃないと overrideは できません。 が、前述した内容を踏まえると、再実装したいメソッドがあるならば、 virtual じゃなくても、再実装はできるし、中で inheritedも 使えます。 (ただし、先祖には影響しないというところを忘れたまま実装を すすめるとバグっぽくなるので注意が必要) また、パラメータリストが違うからといって再実装をあきらめることもありません。 上位クラスで procedure Proc(A: integer); virtual; となっている場合、 下位クラスで procedure Proc(A,B: integer); reintroduce; としても 中で inherited Proc(A) とやっていれば、期待通り動きます。 しかし、 前述のとおり、ご先祖様は Proc(A: integer) のまま アクセスしてくるので、事前にご先祖様の十分な調査が必要です。 dynamicとvirtualの違いはヘルプにあるとおりです。 コーディング段階での制約などは特に違いがありません。 ので補足も特にありません。 #overload overload は全く別物です。 派生、継承うんぬんとは関係がありません。(と思います) procedure Proc(A:integer); overload; //#1 procedure Proc(A:string); overload; //#2 procedure Proc(A,B: integer); overload; //#3 begin Proc(0); // #1 実行 proc('string');// #2 実行 proc(0,1); // #3 実行 end; これだけのことです。 (私的ですが、私は滅多に overload は書かないので、実際のところ 使い勝手など不明なのですが、あまり多用すると、コーディングの時、 型が把握できなくて、大変なのではないかと思います。 まあ…お好みで。) #プロパティ TListViewやTStatusPanels.Items など、VCLの中には property Items[index:integer]: TListItem read GetItem write SetItem; などの GetItemや SetItemが private で virtualじゃない場合が多々あります。 が、あきらめずに、下位クラスで、このまま property Items[index:integer]: TMyListItem read GetItem write SetItem; を再定義しても、表面からたたけるメソッドやプロパティである限り、 期待通り動きます。 privateなGetItemやSetItemにはアクセスできないので プロパティにアクセスします。 Result:= (inherited Items[index]) as TMyListItem; (ただし、インスタンスを作成する部分も再実装や継承などが必要、 かつItemsも同系統の派生である必要がある) ※ 今回 with を使いましたが with 文は、適材適所で、手の抜けるところ意外で使うのは、お勧めしません。 こんなところで、いかがですか。 inherited の使い道…可能性が広がったでしょうか。 DelphiがDelphiであるうちに、ちょっと書いてみたくなりました。 (手遅れという気もしますが) なお、情報の正確性は保証できません。 訂正があれば遠慮なさらず。 Delphi フォーえばーーーーーーーーーーーーー! thanks.
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.