今上位クラスのHOGEに5という値が入っているとします。
上位クラス
TClass1
property HOGE:integer read rhoge write whoge;
TClass2(TClass1)←クラス1を継承
.
.
.
TClass2.method;
var
atai :Integer
begin
atai := HOGE;
end;
上記のように下位クラスのataiにHOGEを代入するとataiが5にはなりません。
わたしの推論ですがHOGEはTClass2のオブジェクトとして扱われているためHOGEには値が入っていないのでしょうか?
上位クラスのHOGEの値をひっぱてきたいのですがどうすればよいでしょうか?
クラスについての勉強が足りないだけだと思います。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TClassA = class
public
value : Integer;
constructor Create;
end;
TClassB = class(TClassA)
public
procedure CheckValue;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TClassA }
constructor TClassA.Create;
begin
value := 10;
end;
{ TClassB }
procedure TClassB.CheckValue;
begin
ShowMessage(IntToStr(value));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ClassB:TClassB;
begin
ClassB :=TClassB.Create;
ClassB.CheckValue;
ClassB.Free;
end;
end.
ちなみに上の質問に追加ですが、
実際にFormCreateなどで
Class1 :=TClass1.Create;
Class2 :=TClass2.Create;
としています。
Class2 :=TClass2.Create;
のみにし、Class2のCreateでinheritedしていた時には、
問題なくHOGEの値が入っていたので、先ほどの推論となりました。
実際に
Class1 :=TClass1.Create;
Class2 :=TClass2.Create;
した場合の状態をしりたいです。
よろしくお願いします。
クラスを別々にCreateしたらそれは別物。
継承元にアクセスしたければ同じインスタンスを使わないといけません。
procedure TForm1.Button1Click(Sender: TObject);
var
ClassB:TClassB;
ClassA:TClassA;
begin
ClassB :=TClassB.Create;
ClassA :=TClassA(ClassB);
ClassA.value := 15;
ClassB.CheckValue;
ClassB.Free;
end;
もう後だしは勘弁です。
後だしすいません。
monnaさんありがとうございます。
大体のことはつかめました。
ではTclassBのインスタンスで、TClassAのプロパティHOGEを使用したい場合は、
TClassB.HOGE := TClassA.HOGE;
とするしかないのですね。
ここで疑問なのですが、継承はたしかに便利ですが、
例えば
TClassA = class
public
value : Integer;
constructor Create;
end;
TClassB = class(TClassA)
public
procedure CheckValue;
end;
これを
TClassA = class
public
value : Integer;
constructor Create;
procedure CheckValue;
end;
とし、
ClassA:TClassA;
ClassA :=TClassA.Create;
とすればBが継承しなくても全て使える気がします。
根本的な話かもしれませんが、TClassB と分けて、継承するメリットがよくわかりません。
オブジェクト指向(志向)についての勉強不足じゃないすか?
メリットがあるから継承するんだよ。
よく自動車で例えて説明されるけど、これが一番分かりやすい。(と思う)
ググったらこんなんもあったよ。
■オブジェクト指向を正しく理解する:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20060921/248617/
一回読んでみるといいよ。
> ではTclassBのインスタンスで、TClassAのプロパティHOGEを使用したい場合は、
> TClassB.HOGE := TClassA.HOGE;
> とするしかないのですね。
そんなことはありません。TClassBのインスタンスは同時にTClassAのインスタンスでもあり、
何もしなくてもTClassAが持っているものをすべて使えます。
var A: TClassA; B: TClassB;
B := TClassB.Create;
A := B; // キャストは要らない
とした場合に
A.value := HOGE;
B.value := HOGE;
どちらでも同じ変数に値が設定されますし、
A.CheckValue();
B.CheckValue();
どちらでも同じメソッドが呼び出されます。
同じですから、わざわざAに代入し直すといった手間をかける必要はないわけです。
これだけだと「同時にTClassAのインスタンスでもある」ということの
メリットが感じられないかもしれませんが、例えば
procedure nantoka(a: TClassA);
のようにTClassAのインスタンスを要求する関数に
nantoka(B);
とTClassBのインスタンスを渡してもちゃんと動作します。
とにかく上でも言われているように、こうした根本的な話はとてもここで説明しきれるものではないし
せっかく説明してもらっても誤った理解で納得してしまう危険性が高いので、
もう少しオブジェクト指向の基本を学習されてからの方がよいと思います。
>継承するメリットがよくわかりません。
TFromの継承
TForm <- TCustomForm <- TScrollingWinControl <- TWinControl <- TControl <- TComponent
TButtonの継承
TButton <- TButtonControl <- TWinControl <- TControl <- TComponent
継承なかったらどうなるか考えればわかるだろ?
TClassA = class
public
value : Integer;
constructor Create;
end;
TClassB = class(TClassA)
public
procedure CheckValue;
end;
これを
TClassA = class
public
value : Integer;
constructor Create;
procedure CheckValue;
end;
このレベルならどっちでも良いだろうけど・・・・
Mr.XRAYです.
ちょっと聞き捨てならない文章が目に付いたので.
>根本的な話かもしれませんが、TClassB と分けて、継承するメリットがよくわかりません。
まさか,継承そのものについて言っているとは思えないのですが,
今回のようなコードでしたら,そうかも知れません.
いや,このような簡単なコードでも,利用価値を考えれば,本当は理解できるとは思っています.
個人的には.
「クラス」と「継承」という概念はDelphiが初めて導入したもので,
これが最大の特徴なんです.
もちろん,今は多くの言語でも導入していますが.
もし,この概念がなかったら,大変です.
これがあるからこそ,例えばTButtonに,ある特定の機能をもつボタンを作成したり
することが可能となっているのです.
もちろん,それだけではありません.
Delphiのバージョンが書いてありませんが(毎度のことですが),Pro版以上でしたら,
VCLのソースコードを是非観てください.
よくぞこんなことを考えたと思うぐらい,
私と,少なくともHalbowさんという方だけかも知れませんが,
見事だと思います.
中古品ですが,以下の書籍も入手可能です.
是非入手して一読されることをお勧めします.
ただし,内容は,人によっては,難しいと思うかも知れません.
Delphiオブジェクト指向プログラミング (ソフトウェアテクノロジー) (単行本)
http://www.amazon.co.jp/gp/offer-listing/4774104272/ref=dp_olp_0?ie=UTF8&qid=1242386650&sr=1-2&condition=all
オブジェクト指向とか継承とかのレベルの前に
クラスとインスタンスについて勉強する必要ありかと。
> 「クラス」と「継承」という概念は Delphi が初めて導入したもので,
これ初耳なんですけど、ホントなんでしょうか?
私がかつて使用していた TurboC/C++ 1.0 や BoralandC/C++ 3.1 などはもちろんこの概念
はありました。BoralandC/C++ にはWindows3.1用のクラスライブラリの他に Turbo Vison と
いうDOS専用のクラスライブラリまでついていました。
これらのC/C++ コンパイラより Delphi(の前身である Turbo Pascal)の方が先に「クラ
ス」や「継承」という概念を先取りしていたということなんでしょうか。
Wikiで調べただけですが、
Turbo Pascal ver5.5からオブジェクト指向を取り入れたみたいですね。
http://ja.wikipedia.org/wiki/Turbo_Pascal
詳しくは書いてありませんがこれが1970年代だとすると
c++は1983年なのでそれよりは早いみたいです。
http://ja.wikipedia.org/wiki/C%2B%2B
オブジェクト指向の歴史のページを見るとTurbo Pascalはばっさり割愛されてるのが多いので本当のところはどうなんでしょうね。
これかな?
http://ja.wikipedia.org/wiki/Simula
上のSimulaの例などを見ると
> 「クラス」と「継承」という概念は Delphi が初めて導入したもので,
とはいえないのでしょうねえ・・・・。
> Turbo Pascal ver5.5からオブジェクト指向を取り入れたみたいですね。
私は Delphi1 が Pascal 初体験だったので技術評論社の「はじめての Pascal」という本
を買いました。この本は「Turbo Pascal 5.5 によるプログラミング技法」というサブタイト
ルがついていますが、いま読み返してみると内容は Pascal 入門に終始していて、オブジェ
クト指向のオの字もでてきません(笑)。初版が 1990 年、私が持っているのは 1992 年発
行なのですが、実際に手に入れたのは当然 Delphi1 が発売された 1995 年以降でしょう。
1990 年ごろといえば DOS 上では C が全盛期だったころじゃないでしょうか。私のように
趣味としてプログラミングを楽しんでいる者にとっては、オブジェクト指向プログラミング
なるものは、ときどき記事で目にすることはあっても、自分とは無縁のものだというような
感じでした。
オブジェクト指向プログラミングとは何かということをきちんと教えてくれたのは上にも
ある塚越さんの本でした。こちらは 1997 年 4 月が初版 1 刷、私のものは同じ年の 6 月に
発行された初版 2 刷。つまりわずか2ヶ月のうちに新たに刷られたわけですが、この手の本
にしては異常なくらいの人気だったことがよくわかりますね。しかし、いま高いんですねえ!
私はDelphi5から始めたので歴史を振り返るといろいろ面白いものがありますね。
そもそもオブジェクト指向ってのは大規模アプリケーションの構築向けで
今でこそ主流でありますが、昔は無用の長物だったみたいですね。
そう考えるとc++、DelphiはまさにPCの大容量化を予見したかのような登場だったのですね。(いや、必要にかられて登場なのかな?)
最近だとC#,Javaのようなバーチャルマシン言語?が登場してますが、われわれは取り残しを食らってるんですかね…。
それは時代があとで教えてくれるんでしょうね。
少なくともDelphiはちと絶滅感が否めませんが ^^;
なんとか盛り返してもらいたいところです。
みなさんありがとうございました。
色々勉強になりました。
どちらにしろやはりまだ勉強不足です。
自分のほうでもっと勉強してから質問するようにします。
また何かありましたらよろしくお願いします。
ツイート | ![]() |