一度Createしたクラスを、そこから派生したクラスとして値を記憶しつづけることはできるのでしょうか?
例えば、
------------------------------------
type
Tc=class(Tobject) end;
Tc_c=class(Tc)
public
A:integer;
B:integer;
end;
var C:Tc;
begin
C:=Tc.Create;
Tc_c(C).A:=1;
Tc_c(C).B:=2;
showmessage('A='+IntToStr(Tc_c(C).A));
showmessage('B='+IntToStr(Tc_c(C).B));
C.Free;
end.
------------------------------------
実行すると、
A=1
B=18
と表示されました。
この代入された値を保存し続けることはできないのでしょうか?
用途は、createする時にはどのクラスとして使うかわからず、後でその変数をそのクラスから継承した違うクラスとして扱いたいのですが、できないでしょうか。
クラスの使い方がよくわかっていません、どなたか知恵を貸していただけませんか。
考え方が逆ですね。
Tc_cは、Tcを継承しているわけですよね。
そして、CreateしているのはTcです。
これを、ほ乳類クラス(Tc)と人間クラス(Tc_c)に置き換えて考えてください。
人間クラスは服を着ており、ポケットが2つ(A,B:Integer)あります。
用意された変数(C)は、ほ乳類クラスです。
ほ乳類クラスの変数には、ほ乳類クラスの実体(インスタンス)が入りました。
さて、この実体には、ポケットがありますか?
変数Cが、Tcクラスであるのはあっています。
このあと、Cには、Tc_cクラスのインスタンスを用意すべきなのです。
C: Tc;という変数は、Tcを継承するすべてのクラスのインスタンス(オブジェクト)を入れることができます。
しかし、そのオブジェクトは、自分を継承したクラスとしては動作しません。
もしこれが動作するなら、すべてのVCLは、TObjectで操作できなければなりませんから。
# これだと破綻しますよね。
わかりました。ということは、
-------------------------------
type
Tc=class(Tobject)
public
A1,A2,A3:integer;
end;
Tc_c=class(Tc) end;
var C:Tc;
D:Tc_c;
begin
C:=Tc.Create;
C.A1:=1;
C.A2:=2;
C.A3:=3;
//Tc_cに置き換える
D:=Tc_c.Create;
D.A1:=C.A1;
D.A2:=C.A2;
D.A3:=C.A3;
C.Free;
C:=D;
//置き換え終了
C.Free;
end.
-----------------------------
これで置き換えが出来ました。
ただ、ここでA1,A2,A3の値をCからDに1個づつコードを書いて移してますが、
このTcのもっている値を、Tc_cに一度に移すことは出来ないでしょうか?
1つずつの処理が面倒な場合は、関数にまとめるとよいです。
たとえば、Assignプロシージャを用意して、指定したクラスから値をコピーするような記述をしておけばできますよね。
VCLでは、Assignプロシージャで値をコピーできます。もちろん、どの値をコピーするかは、Assignプロシージャ内で定義していなければなりません。
やりかたは、abstructなAssignをTcに用意しておき、Tc_cでAssignをオーバーライドします。
これで、TcにTc_cクラスが入っていても、TcのAssignでTc_cのAssignが呼ばれます(つまり、オブジェクトのAssignが呼ばれます)。
スペルミス。Abstractです。
なるほど、
大変勉強になりました。
にしのさん、どうもありがとうございました。
ツイート | ![]() |