いつも拝見させて勉強させてもらっています。
環境はDelphi2007,WindowsXPです。
Aクラス(TOleControl)とBクラス(TOleControl)は
どちらもほぼ同様のプロパティ等を保持しているのが前提です。
プログラム内部でCの変数に対して各用途で使い分けを
していきたいのですが、その方法がわかりません。
CにAクラス、又はBクラスを代入する方法を
教えてください。
下記のようにやりたいのですが、コンパイルエラーがでます。
var
TESTA : A;
TESTB : B;
C : OleVariant;
begin
//TESTA Create
TESTA := A.Create(TESTA);
//TESTB Create
TESTB := B.Create(TESTB);
if(xxx) then
c := TESTA;
end
else begin
c := TESTB;
end;
//Cのプロパティ参照
C.xxxx;
詳しくないので聞き流してください、
多分、クラス設計の概念から行くとこの設計は無理だと思います。
親はあくまで一つじゃなかったでしたっけ?
monaaさん、回答ありがとうございます。
こちらでも色々試してみてますが、
出来そうで出来ないもどかしい状態です。
すみませんが、引き続きよろしくお願い致します。
クラスAとBは親は同じで用途は違うけど同一に扱いたいということ?
こちらのイメージでは印刷と印刷プレビューみたいにプロパティは同じだけど動作が違うのを期待しているのでしたら
フォームにボタンとチェックボックス1つ置いて組んでみました。
書き込み内容をそのまま使おうとすると至る所でエラー出ますけど
それが原因とか言うことは無いですよね?
type
A = class(TOleControl)
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
type
B = class(TOleControl)
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
type
TForm1 = class(TForm)
Button1: TButton;
CheckBox1: TCheckBox;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
TESTA : A;
TESTB : B;
C : TOleControl;
begin
//TESTA Create
TESTA := A.Create(Self);
//TESTB Create
TESTB := B.Create(Self);
if(CheckBox1.Checked) then
c := TESTA
else begin
c := TESTB;
end;
//Cのプロパティ参照
C.Align := alClient;
end;
こうじゃないか?
TO1 = class(TWebBrowser)
private
FA: Integer;
published
property A:Integer read FA write FA;
end;
TO2 = class(TWebBrowser)
private
FB: Integer;
published
property B:Integer read FB write FB;
end;
procedure TForm9.Button1Click(Sender: TObject);
var
O1 : TO1;
O2 : TO2;
O : TOleControl;
begin
O1 := TO1.Create(Self);
O2 := TO2.Create(Self);
if CheckBox1.Checked = True then O := O1 else O := O2;
O.Align := alClient;
O2.Free;
O1.Free;
end;
それだとFAとFBの使いどころが……
状況としてはこういうことをやりたいんですかね?
type
A = class(TOleControl)
property x: Integer;
// その他のAの実装
end;
B = class(TOleControl)
property x: Integer;
// その他のBの実装
end;
...
var C: TOleControl;
...
if xxx then C := TESTA else C := TESTB;
ShowMessage(IntToString(C.x)); // NG
もちろんこれは無理です。(TOleControlはxを持っていないし、
A.xとB.xはたまたま名前が同じだけで無関係なプロパティですから。)
A, Bとも自作のクラスなら共通の親クラスを作ってやればいいのでは。
type
TABParent = class(TOleControl)
property x: Integer;
// その他のA,B共通の実装
end;
A = class(TABParent)
// A固有の実装
end;
B = class(TABParent)
// B固有の実装
end;
...
var P: TABParent;
...
if xxx then P := TESTA else P := TESTB;
ShowMessage(IntToString(P.x)); // OK
xは完全に共通ではなくてAとBで異なる動作をさせたいということなら、
仮想化してそれぞれのクラスでオーバーライドしてやればいいですね。
A,B,xが具体的に何なのかわかりませんが、仮に自作でないとしても
クラス構造をさかのぼっていったら共通の親クラスがいないでしょうか?
tttさんの言うとおり共通の親クラスを定義して
行うことにしました。
monaaさん、takeさん、KHE00221さん、tttさん
本当にありがとうございました。
ツイート | ![]() |