線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4575
推到 Plurk!
推到 Facebook!

類別的類別(class of)的問題

答題得分者是:pcplayer99
waterful0
一般會員


發表:7
回覆:12
積分:3
註冊:2006-07-12

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-07-15 20:53:12 IP:210.60.xxx.xxx 未訂閱

能否幫我大概解釋一下,萬分感謝。

舉例來說:

type

TControlClass = class of Tcontrol;

那麼

var

ControlClass : TControlClass;

我一樣可以

ControlClass := TControlClass.create嗎?

如果可以的話,那麼所建構出來

ControlClass 是一個物件 還是一種類別?

還有:

type

TControlClass = class of TControl;

type

TMyControl = class(Tcontrol);

又有何不同之處?

問的順序可能有點反了,不好意思!

pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2006-07-16 11:58:02 IP:218.18.xxx.xxx 未訂閱
TMyControlClass = class of TMyControl ,这句话的意思,是定义了一个叫做 TMyControlClass 的类别,它代表对类别 TMyControl 的引用。似乎可以理解为它是 TMyControl 的一个别名。

因为它仅仅是一个类别定义的别名,你不可以 Create 它。因为它不是一个 Variant,仅仅是一个类别定义。

你定义一个 Var, 比如:

var
MyControl: TMyControl; 这个 var 是一个 TMyControl 类别的 var,它才是可以 Create 的一个具体的物件的名字.
waterful0
一般會員


發表:7
回覆:12
積分:3
註冊:2006-07-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2006-07-20 16:21:53 IP:220.134.xxx.xxx 未訂閱

01 Type

02 TControlClass = class of TControl;

...

03 function CreateControl(ControlClass: TControlClass; const ControlName: string; X, Y, W, H: integer): TControl;

04 begin

05 Result := ControlClass.Create(Application.MainForm);

06 with Result do

07 begin

08 parent := Application.MainForm;

09 Name := ControlName;

10 SetBounds(X, Y, W, H);

11 Visible := True;

12 end;

13 procedure TForm1.Button1Click(Sender: TObject);

14 begin

15 CreateControl(TEdit, 'Edit1', 10,10,100, 200);

16 CreateControl(TButton, 'Button2', 120, 10, 80, 30);

17 end;

//取材自錢達智先生所著「delphi學習筆記win32基礎篇」

//先請問一下,為什麼我的行距這麼寬,如何調小呢?

謝謝你的回答,用別名來理解的話,的確是比較容易理解。可是

在05行時不是就Create了嗎?還是我有哪個地方會錯意了?

syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#4 引用回覆 回覆 發表時間:2006-07-21 22:39:20 IP:61.64.xxx.xxx 未訂閱
要是說,我們可以定義一個物件,然後再創造來用,表示你的物件導向設計觀念不對
直接創造就可以使用,何必脫褲子放屁,多個定義?

很簡單,一個觀念
類別 是被 「定義」,不能被創造,「定義」乃存在於「程式設計時期」
物件 是被 「創造」,不能被定義,「創造」乃運作於「程式執行時期」
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#5 引用回覆 回覆 發表時間:2006-07-21 22:44:08 IP:61.64.xxx.xxx 未訂閱
這也不對,他不是別名,這位仁兄可能 C 程式寫太多,又不甚瞭解物件精神
TMyControlClass 是 TMyControl 的 SubClass 或是我們常稱的子代、後代,也不適合用「引用」來形容,應該使用「繼承」
TMyControl 是 TMyControlClass 的父代

「別名」表示兩者「一樣、等效」,但「一樣」不必表就是「別名」

===================引 用 文 章===================
TMyControlClass = class of TMyControl ,这句话的意思,是定义了一个叫做 TMyControlClass 的类别,它代表对类别 TMyControl 的引用。似乎可以理解为它是 TMyControl 的一个别名。

因为它仅仅是一个类别定义的别名,你不可以 Create 它。因为它不是一个 Variant,仅仅是一个类别定义。

你定义一个 Var, 比如:

var
MyControl: TMyControl; 这个 var 是一个 TMyControl 类别的 var,它才是可以 Create 的一个具体的物件的名字.
pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2006-07-24 00:40:36 IP:219.134.xxx.xxx 未訂閱
老兄,你错了。

TMyControlClass = class of TMyControl , 不是子代,后代。

TMyControl2=class(TMyControl) 这个 TMycontrol2 才是 TMyControl 的子代,后代。

看看 delphi 的 help 怎么说的吧:

A class-reference type, sometimes called a metaclass, is denoted by a construction of the form

class of type

where type is any class type. The identifier type itself denotes a value whose type is class of type. If type1 is an ancestor of type2, then class of type2 is assignment-compatible with class of type1. Thus

type TClass = class of TObject;
var AnyObj: TClass;

declares a variable called AnyObj that can hold a reference to any class. (The definition of a class-reference type cannot occur directly in a variable declaration or parameter list.) You can assign the value nil to a variable of any class-reference type.

To see how class-reference types are used, look at the declaration of the constructor for TCollection (in the Classes unit):

type TCollectionItemClass = class of TCollectionItem;
...
constructor Create(ItemClass: TCollectionItemClass);

This declaration says that to create a TCollection instance object, you must pass to the constructor the name of a class descending from TCollectionItem.

Class-reference types are useful when you want to invoke a class method or virtual constructor on a class or object whose actual type is unknown at compile time.

--------------
这里,它明确地说,这是 A class-reference type,

其实,类引用有很多用处。比如,你写了个 function,在这个 function 里,你不知道你将会 Create 一个button,还是一个 Edit,但他们都是 TControl 的子代,所以,你可以这样写:

function CreateMyControl(AControlClass:TControlClass);
var
AControl:TControl;
begin
AControl := AControlClas.Create;
AControl.Left := 100;
AControl.Top := 20;
end;

然后,你可以这样来:

CreateMyControl(TEdit); //这里,create 了一个 TEdit 类别的物件。
CreateMyControl(TButton); // 这里,你 Create 了一个 TButton 类别的物件!

===================引 用 文 章===================
這也不對,他不是別名,這位仁兄可能 C 程式寫太多,又不甚瞭解物件精神
TMyControlClass 是 TMyControl 的 SubClass 或是我們常稱的子代、後代,也不適合用「引用」來形容,應該使用「繼承」
TMyControl 是 TMyControlClass 的父代

「別名」表示兩者「一樣、等效」,但「一樣」不必表就是「別名」

===================引 用 文 章===================
TMyControlClass = class of TMyControl ,这句话的意思,是定义了一个叫做 TMyControlClass 的类别,它代表对类别 TMyControl 的引用。似乎可以理解为它是 TMyControl 的一个别名。

因为它仅仅是一个类别定义的别名,你不可以 Create 它。因为它不是一个 Variant,仅仅是一个类别定义。

你定义一个 Var, 比如:

var
MyControl: TMyControl; 这个 var 是一个 TMyControl 类别的 var,它才是可以 Create 的一个具体的物件的名字.
waterful0
一般會員


發表:7
回覆:12
積分:3
註冊:2006-07-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2006-07-24 11:03:12 IP:220.134.xxx.xxx 未訂閱


===================引 用 文 章===================
这里,它明确地说,这是 A class-reference type,

其实,类引用有很多用处。比如,你写了个 function,在这个 function 里,你不知道你将会 Create 一个button,还是一个 Edit,但他们都是 TControl 的子代,所以,你可以这样写:

function CreateMyControl(AControlClass:TControlClass);
var
AControl:TControl;
begin
AControl := AControlClas.Create;
AControl.Left := 100;
AControl.Top := 20;
end;

然后,你可以这样来:

CreateMyControl(TEdit); //这里,create 了一个 TEdit 类别的物件。
CreateMyControl(TButton); // 这里,你 Create 了一个 TButton 类别的物件!

======================================================================

那關於類引用,在
上面紫色類別部份

function CreateMyControl(AControlClass:TControlClass);
改成
function CreateMyControl(AControlClass:TControl);
的話,代表
只能傳入(TControl)
CreateMyControl(TControl);

而無法傳入繼承他的其它子代類別了(TControl,TEdit,TButton......)
CreateMyControl(TEdit);
CreateMyControl(TButton);


是這樣嗎?

而類引用,還有常用在哪些地方?如果可以的話,是否能夠舉例說明,謝謝了。

pcplayer99
尊榮會員


發表:146
回覆:790
積分:632
註冊:2003-01-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2006-07-24 15:29:52 IP:218.18.xxx.xxx 未訂閱
function CreateMyControl(AControlClass:TControlClass);
改成
function CreateMyControl(AControlClass:TControl);

请注意,在这里,把 TControlClass 改为 TControl,意思就完全变了!

第一个 AControlClass:TControlClass 第二个,(AControlClass:TControl); 表示这里要传入一个变数(一个 var)这个变数的类型是 TControl。

完全是两个不同的意思!

通常的变数,假设你有3个TButton,Button1, Button2, Button2,你要修改 Button 上的 Caption:

procedure ChangeCaption(AButton: TButton);
begin
if AButton = Button1 then AButton.Caption := 'abc' else if AButton = Button2 then AButton.Caption := '123';
end;

你可以把你的 Button1 当作变数送进这个 procedure 里去:

ChangeCaption(Button1); <---- 这里送进去一个 TButton 类型的变数!

---------------

现在,更进一步:
procedure ChangeCaption(AButton: TControl);
begin
if AButton = Button1 then AButton.Caption := 'abc' else if AButton = Button2 then AButton.Caption := '123'
else if AButton is TEdit then TEdit(AButton).Text := 'this is a Edit';
end;

你可以: ChangeCaption(Edit1);

在这里,实际上是用了“多态”。因为 TEdit 和 TButton 都是从 TControl 继承下来的。

不过,在这里用多态,你传入的还是一个变数,当然,任何变数都是某个类别的。可能是 TButton,可能是 TEdit.
------------------------

但是,如果你都不知道你要处理的东东是个什么东东,是什么类别的东东,并且你要根据类别的不同,做不同的操作,那么:

TControl -- 一个类别定义
TButton --- 一个类别定义
TEdit --- 一个类别定义

TButtonClass = class of TButton -----类别 TButton 的引用!
TControlClass = class of TControl --- 类别 TControl 的引用!

AControlClass: TControlClass --- 定义了一个变数,这个变数不是一个类别的变数。可以看成它就是类别。它不可以做如下操作:

AControlClass := TControlClass.Create,不可以这样操作。而以个 Button1 := TButton.Create 是可以的!

不可以做这样的操作的原因是,AControlClass 本身就是一个类别定义,而不是一个普通的 TControl 类别的变数。




===================引 用 文 章===================



那關於類引用,在
上面紫色類別部份

function CreateMyControl(AControlClass:TControlClass);
改成
function CreateMyControl(AControlClass:TControl);
的話,代表
只能傳入(TControl)
CreateMyControl(TControl);

而無法傳入繼承他的其它子代類別了(TControl,TEdit,TButton......)
CreateMyControl(TEdit);
CreateMyControl(TButton);


是這樣嗎?

而類引用,還有常用在哪些地方?如果可以的話,是否能夠舉例說明,謝謝了。

waterful0
一般會員


發表:7
回覆:12
積分:3
註冊:2006-07-12

發送簡訊給我
#9 引用回覆 回覆 發表時間:2006-07-25 13:38:29 IP:220.134.xxx.xxx 未訂閱

謝謝您的指導,解釋的非常清楚,讓我頓時豁然開朗,

不好意思讓您費心了。謝謝。

A022
一般會員


發表:18
回覆:29
積分:9
註冊:2002-06-21

發送簡訊給我
#10 引用回覆 回覆 發表時間:2018-03-30 18:43:13 IP:1.167.xxx.xxx 未訂閱
Can a Metaclass be derived in delphi?ruby can.or var winclass:twincontrolclass; . . . If winclass is tcontrolclass then tcontrolclass(winclass).left:=12.... like this.也許語法有些錯誤但只是說can 'a metaclass be derived? And can be upcasting? Thanks!
編輯記錄
A022 重新編輯於 2018-03-30 19:19:27, 註解 無‧
A022 重新編輯於 2018-03-30 20:31:14, 註解 無‧
A022 重新編輯於 2018-03-30 20:34:58, 註解 無‧
系統時間:2024-04-25 22:14:01
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!