雄
雄仔
Unregistered / Unconfirmed
GUEST, unregistred user!
为帮助大家对DELPHI的VCL库进一步了解。
本人决定对VCL进行讲解。
欢迎志同道合的朋友一起探讨、学习。
英文例子如下:
1、Classes and objects
A class, or class type, defines a structure consisting of fields, methods, and properties. Instances of a class type are called objects. The fields, methods, and properties of a class are called its components or members.
A field is essentially a variable that is part of an object. Like the fields of a record, a class抯 fields represent data items that exist in each instance of the class.
A method is a procedure or function associated with a class. Most methods operate on objects梩hat is, instances of a class. Some methods (called class methods) operate on class types themselves.
A property is an interface to data associated with an object (often stored in a field). Properties have access specifiers, which determine how their data are read and modified. From other parts of a program梠utside of the object itself梐 property appears in most respects like a field.
Objects are dynamically allocated blocks of memory whose structure is determined by their class type. Each object has a unique copy of every field defined in the class, but all instances of a class share the same methods. Objects are created and destroyed by special methods called constructors and destructors.
A variable of a class type is actually a pointer that references an object. Hence more than one variable can refer to the same object. Like other pointers, class-type variables can hold the value nil. But you don抰 have to explicitly dereference a class-type variable to access the object it points to. For example, SomeObject.Size := 100 assigns the value 100 to the Size property of the object referenced by SomeObject
you would not write this as SomeObject^.Size := 100.
2、About class types
A class type must be declared and given a name before it can be instantiated. (You cannot define a class type within a variable declaration.) Declare classes only in the outermost scope of a program or unit, not in a procedure or function declaration.
A class type declaration has the form
type className = class (ancestorClass)
memberList
end;
where className is any valid identifier, (ancestorClass) is optional, and memberList declares members梩hat is, fields, methods, and properties梠f the class. If you omit (
ancestorClass), then the new class inherits directly from the predefined TObject class. If you include (ancestorClass) and memberList is empty, you can omit end. A class type declaration can also include a list of interfaces implemented by the class
see Implementing interfaces.
Methods appear in a class declaration as function or procedure headings, with no body. Defining declarations for each method occur elsewhere in the program.
For example, here is the declaration of the TListColumns class from the ComCtrls unit of Delphi抯 VCL.
type
TListColumns = class(TCollection)
private
FOwner: TCustomListView;
function GetItem(Index: Integer): TListColumn;
procedure SetItem(Index: Integer
Value: TListColumn);
protected
function GetOwner: TPersistent
override;
procedure Update(Item: TCollectionItem)
override;
public
constructor Create(AOwner: TCustomListView);
function Add: TListColumn;
property Owner: TCustomListView read FOwner;
property Items[Index: Integer]: TListColumn read GetItem write SetItem
default;
end;
TListColumns descends from TCollection (in the Classes unit), inheriting most of its members. But it defines梠r redefines梥everal methods and properties, including its constructor method, Create. Its destructor, Destroy, is inherited without change from TCollection, and so is not redeclared. Each member is declared as private, protected, or
public (this class has no published members)
for explanations of these terms, see Visibility of class members.
Given this declaration, we can create a TListColumns with
var ListColumns: TListColumns;
ListColumns := TListColumns.Create(SomeListView);
where SomeListView is a variable that holds a TCustomListView obje
3、Inheritance and scope
When you declare a class, you can specify its immediate ancestor. For example,
type TSomeControl = class(TWinControl);
declares a class called TSomeControl that descends from TWinControl. A class type automatically inherits all of the members from its immediate ancestor. Each class can declare new members and can redefine inherited ones, but a class cannot remove members defined in an ancestor. Hence TSomeControl contains all of the members defined in TWinControl and in each of TWinControl憇 ancestors.
The scope of a member抯 identifier starts at the point where the member is declared, continues to the end of the class declaration, and extends over all descendants of the class and the blocks of all methods defined in the class and its descendants.
4、TObject and Tclass
he TObject class, declared in the System unit, is the ultimate ancestor of all other classes. TObject defines only a handful of methods, including a basic constructor and destructor. In addition to TObject, the System unit declares the class-reference type TClass:
TClass = class of TObject;
If the declaration of a class type doesn抰 specify an ancestor, the class inherits directly from TObject. Thus
type TMyClass = class
...
end;
is equivalent to
type TMyClass = class(TObject)
...
end;
The latter form is recommended for readability.
5、Compatibility of class types
A class type is assignment-compatible with its ancestors. Hence a variable of a class type can reference an instance of any descendant type. For example, given the declarations
type
TFigure = class(TObject);
TRectangle = class(TFigure);
TSquare = class(TRectangle);
var
Fig: TFigure;
the variable Fig can be assigned values of type TFigure, TRectangle, and TSquare.
6、Object types
As an alternative to class types, you can declare object types using the syntax
type objectTypeName = object (ancestorObjectType)
memberList
end;
where objectTypeName is any valid identifier, (ancestorObjectType) is optional, and memberList declares fields, methods, and properties. If (ancestorObjectType) is omitted, then the new type has no ancestor. Object types cannot have published members.
Since object types do not descend from TObject, they provide no built-in constructors, destructors, or other methods. You can create instances of an object type using the New procedure and destroy them with the Dispose procedure, or you can simply declare variables of an object type, just as you would with records.
Object types are supported for backward compatibility only. Their use is not recommended.
7、Visibility of class members
Every member of a class has an attribute called visibility, which is indicated by one of the reserved words private, protected, public, published, or automated. For example,
published property Color: TColor read GetColor write SetColor;
declares a published property called Color. Visibility determines where and how a member can be accessed, with private representing the least accessibility, protected representing an intermediate level of accessibility, and public, published, and automated representing the greatest accessibility.
Private, protected, and public members
Published members
Automated members
If a member抯 declaration appears without its own visibility specifier, the member has the same visibility as the one that precedes it. Members at the beginning of a class declaration that don抰 have a specified visibility are by default published, provided the class is compiled in the {$M+} state or is derived from a class compiled in the {$M+} state
otherwise, such members are public.
For readability, it is best to organize a class declaration by visibility, placing all the private members together, followed by all the protected members, and so forth. This way each visibility reserved word appears at most once and marks the beginning of a new 搒ection?of the declaration. So a typical class declaration should like this:
type
TMyClass = class(TControl)
private
... { private declarations here}
protected
... { protected declarations here }
public
... { public declarations here }
published
... { published declarations here }
end;
You can increase the visibility of a member in a descendant class by redeclaring it, but you cannot decrease its visibility. For example, a protected property can be made public in a descendant, but not private. Moreover, published members cannot become public in a descendant class. For more information, see Property overrides and
8、Private, protected, and public members
A private member is invisible outside of the unit or program where its class is declared. In other words, a private method cannot be called from another module, and a private field or property cannot be read or written to from another module. By placing related class declarations in the same module, you can give the classes access to one another抯 private members without making those members more widely accessible.
A protected member is visible anywhere in the module where its class is declared and from any descendant class, regardless of the module where the descendant class appears. In other words, a protected method can be called, and a protected field or property read or written to, from the definition of any method belonging to a class that descends from the one where the protected member is declared. Members that are intended for use only in the implementation of derived classes are usually protected.
A public member is visible wherever its class can be referenced.
9、Published members
Published members have the same visibility as public members. The difference is that runtime type information (RTTI) is generated for published members. RTTI allows an application to query the fields and properties of an object dynamically and to locate its methods. Delphi uses RTTI to access the values of properties when saving and loading form (.DFM) files, to display properties in the Object Inspector, and to associate specific methods (called event handlers) with specific properties (called events).
Published properties are restricted to certain data types. Ordinal, string, class, interface, and method-pointer types can be published. So can set types, provided the upper and lower bounds of the base type have ordinal values between 0 and 31. (In other words, the set must fit in a byte, word, or double word.) Any real type except Real48 can be published. Array properties cannot be published.
All methods are publishable, but a class cannot publish two or more overloaded methods with the same name. Fields can be published only if they are of a class or interface type.
A class cannot have published members unless it is compiled in the {$M+} state or descends from a class compiled in the {$M+} state. Most classes with published members derive from TPersistent, which is compiled in the {$M+} state, so it is seldom necessary to use the $M directive.
10、Automated members
Automated members have the same visibility as public members. The difference is that Automation type information (required for Automation servers) is generated for automated members. Automated members typically appear only in classes derived from the TAutoObject class in the OleAuto unit. This unit, and the automated reserved word itself, are maintained for backward compatibility. The TAutoObject class in the ComObj unit does not use automated.
The following restrictions apply to methods and properties declared as automated.
The types of all properties, array property parameters, method parameters, and function results must be automatable. The automatable types are Byte, Currency, Real,
Double, Longint, Integer, Single, Smallint, AnsiString, WideString, TDateTime, Variant, OleVariant, WordBool, and all interface types.
Method declarations must use the default register calling convention. They can be virtual, but not dynamic.
Property declarations can include access specifiers (read and write) but other specifiers (index, stored, default, and nodefault) are not allowed. Access specifiers must list a method identifier that uses the default register calling convention
field identifiers are not allowed.
Property declarations must specify a type. Property overrides are not allowed.
The declaration of an automated method or property can include a dispid directive, which must be followed by an integer constant that specifies an Automation dispatch ID for the member. Otherwise, the compiler automatically assigns the member a dispatch ID that is one larger than the largest dispatch ID used by any method or property in the class and its ancestors. Specifying an already used ID in a dispid directive causes an error.
For more information about Automation, see Automation objects.
本人决定对VCL进行讲解。
欢迎志同道合的朋友一起探讨、学习。
英文例子如下:
1、Classes and objects
A class, or class type, defines a structure consisting of fields, methods, and properties. Instances of a class type are called objects. The fields, methods, and properties of a class are called its components or members.
A field is essentially a variable that is part of an object. Like the fields of a record, a class抯 fields represent data items that exist in each instance of the class.
A method is a procedure or function associated with a class. Most methods operate on objects梩hat is, instances of a class. Some methods (called class methods) operate on class types themselves.
A property is an interface to data associated with an object (often stored in a field). Properties have access specifiers, which determine how their data are read and modified. From other parts of a program梠utside of the object itself梐 property appears in most respects like a field.
Objects are dynamically allocated blocks of memory whose structure is determined by their class type. Each object has a unique copy of every field defined in the class, but all instances of a class share the same methods. Objects are created and destroyed by special methods called constructors and destructors.
A variable of a class type is actually a pointer that references an object. Hence more than one variable can refer to the same object. Like other pointers, class-type variables can hold the value nil. But you don抰 have to explicitly dereference a class-type variable to access the object it points to. For example, SomeObject.Size := 100 assigns the value 100 to the Size property of the object referenced by SomeObject
you would not write this as SomeObject^.Size := 100.
2、About class types
A class type must be declared and given a name before it can be instantiated. (You cannot define a class type within a variable declaration.) Declare classes only in the outermost scope of a program or unit, not in a procedure or function declaration.
A class type declaration has the form
type className = class (ancestorClass)
memberList
end;
where className is any valid identifier, (ancestorClass) is optional, and memberList declares members梩hat is, fields, methods, and properties梠f the class. If you omit (
ancestorClass), then the new class inherits directly from the predefined TObject class. If you include (ancestorClass) and memberList is empty, you can omit end. A class type declaration can also include a list of interfaces implemented by the class
see Implementing interfaces.
Methods appear in a class declaration as function or procedure headings, with no body. Defining declarations for each method occur elsewhere in the program.
For example, here is the declaration of the TListColumns class from the ComCtrls unit of Delphi抯 VCL.
type
TListColumns = class(TCollection)
private
FOwner: TCustomListView;
function GetItem(Index: Integer): TListColumn;
procedure SetItem(Index: Integer
Value: TListColumn);
protected
function GetOwner: TPersistent
override;
procedure Update(Item: TCollectionItem)
override;
public
constructor Create(AOwner: TCustomListView);
function Add: TListColumn;
property Owner: TCustomListView read FOwner;
property Items[Index: Integer]: TListColumn read GetItem write SetItem
default;
end;
TListColumns descends from TCollection (in the Classes unit), inheriting most of its members. But it defines梠r redefines梥everal methods and properties, including its constructor method, Create. Its destructor, Destroy, is inherited without change from TCollection, and so is not redeclared. Each member is declared as private, protected, or
public (this class has no published members)
for explanations of these terms, see Visibility of class members.
Given this declaration, we can create a TListColumns with
var ListColumns: TListColumns;
ListColumns := TListColumns.Create(SomeListView);
where SomeListView is a variable that holds a TCustomListView obje
3、Inheritance and scope
When you declare a class, you can specify its immediate ancestor. For example,
type TSomeControl = class(TWinControl);
declares a class called TSomeControl that descends from TWinControl. A class type automatically inherits all of the members from its immediate ancestor. Each class can declare new members and can redefine inherited ones, but a class cannot remove members defined in an ancestor. Hence TSomeControl contains all of the members defined in TWinControl and in each of TWinControl憇 ancestors.
The scope of a member抯 identifier starts at the point where the member is declared, continues to the end of the class declaration, and extends over all descendants of the class and the blocks of all methods defined in the class and its descendants.
4、TObject and Tclass
he TObject class, declared in the System unit, is the ultimate ancestor of all other classes. TObject defines only a handful of methods, including a basic constructor and destructor. In addition to TObject, the System unit declares the class-reference type TClass:
TClass = class of TObject;
If the declaration of a class type doesn抰 specify an ancestor, the class inherits directly from TObject. Thus
type TMyClass = class
...
end;
is equivalent to
type TMyClass = class(TObject)
...
end;
The latter form is recommended for readability.
5、Compatibility of class types
A class type is assignment-compatible with its ancestors. Hence a variable of a class type can reference an instance of any descendant type. For example, given the declarations
type
TFigure = class(TObject);
TRectangle = class(TFigure);
TSquare = class(TRectangle);
var
Fig: TFigure;
the variable Fig can be assigned values of type TFigure, TRectangle, and TSquare.
6、Object types
As an alternative to class types, you can declare object types using the syntax
type objectTypeName = object (ancestorObjectType)
memberList
end;
where objectTypeName is any valid identifier, (ancestorObjectType) is optional, and memberList declares fields, methods, and properties. If (ancestorObjectType) is omitted, then the new type has no ancestor. Object types cannot have published members.
Since object types do not descend from TObject, they provide no built-in constructors, destructors, or other methods. You can create instances of an object type using the New procedure and destroy them with the Dispose procedure, or you can simply declare variables of an object type, just as you would with records.
Object types are supported for backward compatibility only. Their use is not recommended.
7、Visibility of class members
Every member of a class has an attribute called visibility, which is indicated by one of the reserved words private, protected, public, published, or automated. For example,
published property Color: TColor read GetColor write SetColor;
declares a published property called Color. Visibility determines where and how a member can be accessed, with private representing the least accessibility, protected representing an intermediate level of accessibility, and public, published, and automated representing the greatest accessibility.
Private, protected, and public members
Published members
Automated members
If a member抯 declaration appears without its own visibility specifier, the member has the same visibility as the one that precedes it. Members at the beginning of a class declaration that don抰 have a specified visibility are by default published, provided the class is compiled in the {$M+} state or is derived from a class compiled in the {$M+} state
otherwise, such members are public.
For readability, it is best to organize a class declaration by visibility, placing all the private members together, followed by all the protected members, and so forth. This way each visibility reserved word appears at most once and marks the beginning of a new 搒ection?of the declaration. So a typical class declaration should like this:
type
TMyClass = class(TControl)
private
... { private declarations here}
protected
... { protected declarations here }
public
... { public declarations here }
published
... { published declarations here }
end;
You can increase the visibility of a member in a descendant class by redeclaring it, but you cannot decrease its visibility. For example, a protected property can be made public in a descendant, but not private. Moreover, published members cannot become public in a descendant class. For more information, see Property overrides and
8、Private, protected, and public members
A private member is invisible outside of the unit or program where its class is declared. In other words, a private method cannot be called from another module, and a private field or property cannot be read or written to from another module. By placing related class declarations in the same module, you can give the classes access to one another抯 private members without making those members more widely accessible.
A protected member is visible anywhere in the module where its class is declared and from any descendant class, regardless of the module where the descendant class appears. In other words, a protected method can be called, and a protected field or property read or written to, from the definition of any method belonging to a class that descends from the one where the protected member is declared. Members that are intended for use only in the implementation of derived classes are usually protected.
A public member is visible wherever its class can be referenced.
9、Published members
Published members have the same visibility as public members. The difference is that runtime type information (RTTI) is generated for published members. RTTI allows an application to query the fields and properties of an object dynamically and to locate its methods. Delphi uses RTTI to access the values of properties when saving and loading form (.DFM) files, to display properties in the Object Inspector, and to associate specific methods (called event handlers) with specific properties (called events).
Published properties are restricted to certain data types. Ordinal, string, class, interface, and method-pointer types can be published. So can set types, provided the upper and lower bounds of the base type have ordinal values between 0 and 31. (In other words, the set must fit in a byte, word, or double word.) Any real type except Real48 can be published. Array properties cannot be published.
All methods are publishable, but a class cannot publish two or more overloaded methods with the same name. Fields can be published only if they are of a class or interface type.
A class cannot have published members unless it is compiled in the {$M+} state or descends from a class compiled in the {$M+} state. Most classes with published members derive from TPersistent, which is compiled in the {$M+} state, so it is seldom necessary to use the $M directive.
10、Automated members
Automated members have the same visibility as public members. The difference is that Automation type information (required for Automation servers) is generated for automated members. Automated members typically appear only in classes derived from the TAutoObject class in the OleAuto unit. This unit, and the automated reserved word itself, are maintained for backward compatibility. The TAutoObject class in the ComObj unit does not use automated.
The following restrictions apply to methods and properties declared as automated.
The types of all properties, array property parameters, method parameters, and function results must be automatable. The automatable types are Byte, Currency, Real,
Double, Longint, Integer, Single, Smallint, AnsiString, WideString, TDateTime, Variant, OleVariant, WordBool, and all interface types.
Method declarations must use the default register calling convention. They can be virtual, but not dynamic.
Property declarations can include access specifiers (read and write) but other specifiers (index, stored, default, and nodefault) are not allowed. Access specifiers must list a method identifier that uses the default register calling convention
field identifiers are not allowed.
Property declarations must specify a type. Property overrides are not allowed.
The declaration of an automated method or property can include a dispid directive, which must be followed by an integer constant that specifies an Automation dispatch ID for the member. Otherwise, the compiler automatically assigns the member a dispatch ID that is one larger than the largest dispatch ID used by any method or property in the class and its ancestors. Specifying an already used ID in a dispid directive causes an error.
For more information about Automation, see Automation objects.