クラスの継承についてわからないことがあります

解決


G46  2009-05-15 05:22:31  No: 34396

今上位クラスの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の値をひっぱてきたいのですがどうすればよいでしょうか?


monaa  2009-05-15 05:40:23  No: 34397

クラスについての勉強が足りないだけだと思います。

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.


G46  2009-05-15 05:43:29  No: 34398

ちなみに上の質問に追加ですが、
実際にFormCreateなどで
Class1 :=TClass1.Create; 
Class2 :=TClass2.Create;
としています。

Class2 :=TClass2.Create;
のみにし、Class2のCreateでinheritedしていた時には、
問題なくHOGEの値が入っていたので、先ほどの推論となりました。

実際に
Class1 :=TClass1.Create; 
Class2 :=TClass2.Create;
した場合の状態をしりたいです。
よろしくお願いします。


monaa  2009-05-15 06:33:55  No: 34399

クラスを別々に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;

もう後だしは勘弁です。


G46  2009-05-15 19:05:47  No: 34400

後だしすいません。
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 と分けて、継承するメリットがよくわかりません。


majide  2009-05-15 22:16:59  No: 34401

オブジェクト指向(志向)についての勉強不足じゃないすか?
メリットがあるから継承するんだよ。

よく自動車で例えて説明されるけど、これが一番分かりやすい。(と思う)
ググったらこんなんもあったよ。

■オブジェクト指向を正しく理解する:ITpro
http://itpro.nikkeibp.co.jp/article/COLUMN/20060921/248617/

一回読んでみるといいよ。


toc  2009-05-15 22:28:42  No: 34402

> では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のインスタンスを渡してもちゃんと動作します。

とにかく上でも言われているように、こうした根本的な話はとてもここで説明しきれるものではないし
せっかく説明してもらっても誤った理解で納得してしまう危険性が高いので、
もう少しオブジェクト指向の基本を学習されてからの方がよいと思います。


KHE00221  2009-05-16 04:37:15  No: 34403

>継承するメリットがよくわかりません。

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  2009-05-16 05:39:28  No: 34404

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


辛口だけど  2009-05-16 07:48:48  No: 34405

オブジェクト指向とか継承とかのレベルの前に
クラスとインスタンスについて勉強する必要ありかと。


えっ! ほんとですか?  2009-05-17 06:21:42  No: 34406

> 「クラス」と「継承」という概念は Delphi が初めて導入したもので,
  これ初耳なんですけど、ホントなんでしょうか?
  私がかつて使用していた TurboC/C++ 1.0 や BoralandC/C++ 3.1 などはもちろんこの概念
はありました。BoralandC/C++ にはWindows3.1用のクラスライブラリの他に Turbo Vison と
いうDOS専用のクラスライブラリまでついていました。
  これらのC/C++ コンパイラより Delphi(の前身である Turbo Pascal)の方が先に「クラ
ス」や「継承」という概念を先取りしていたということなんでしょうか。


monaa  2009-05-17 11:37:13  No: 34407

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はばっさり割愛されてるのが多いので本当のところはどうなんでしょうね。


これかな?  2009-05-17 19:22:05  No: 34408

これかな?
http://ja.wikipedia.org/wiki/Simula


えっ! ほんとですか? Part2  2009-05-17 20:38:12  No: 34409

上の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ヶ月のうちに新たに刷られたわけですが、この手の本
にしては異常なくらいの人気だったことがよくわかりますね。しかし、いま高いんですねえ!


monaa  2009-05-18 00:18:41  No: 34410

私はDelphi5から始めたので歴史を振り返るといろいろ面白いものがありますね。
そもそもオブジェクト指向ってのは大規模アプリケーションの構築向けで
今でこそ主流でありますが、昔は無用の長物だったみたいですね。
そう考えるとc++、DelphiはまさにPCの大容量化を予見したかのような登場だったのですね。(いや、必要にかられて登場なのかな?)
最近だとC#,Javaのようなバーチャルマシン言語?が登場してますが、われわれは取り残しを食らってるんですかね…。
それは時代があとで教えてくれるんでしょうね。
少なくともDelphiはちと絶滅感が否めませんが ^^;
なんとか盛り返してもらいたいところです。


G46  2009-05-18 19:54:14  No: 34411

みなさんありがとうございました。
色々勉強になりました。
どちらにしろやはりまだ勉強不足です。
自分のほうでもっと勉強してから質問するようにします。

また何かありましたらよろしくお願いします。


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

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






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