Delphi Object Model (Part IV)
Delphi is rich and powerful for object-oriented programming. In addition to traditional classes and objects, Delphi also provides features such as interface, abnormal processing, multi-threaded programming. This chapter explains the object model of Delphi. The reader should be familiar with the standard Pascal and have a certain understanding of the basic law on object-oriented programming.
(The original text of this article will decompose Delphi and Object Pascal as Delphi, may have a conceptual suspected. However, in most cases, I believe that readers can determine the specific meaning of Delphi described in the text according to context - Translator's Note .)
Lifecycle of Object Life Cycle object
For most objects, you call the constructor to create it, use it, and then call free to release it. Delphi handles all other details for you. Perhaps, sometimes you need to learn more about the implementation mechanism within the Delphi object model. Example 2-8 shows how to simulate Delphi creation and release an object.
Example 2-8: Life Cycle of Objects
Type
Tsomething = Class
Procedure dosomething;
END;
VAR
REF: Tsomething;
Begin
Ref: = tsomething.create;
Ref.dosomething;
REF.FREE;
END;
// The hidden code is similar to this in the constructor:
Function Tsomething.create (IsclassRef: Boolean): Tsomething;
Begin
IF IsclassRef Then
Try
// Get a new object instance
Self: = tsomething.newinstance;
// newInstance initializes the object, the function is similar to InitInstance. If you override newinstance, then,
/ / Do not call Inherited NewInstance, but should call InitInstance.
// This call is as shown below, so you can know what happened,
/ / But keep in mind that Delphi does not actually call InitInstance.
InitInstance (Self);
// Do the constructor really want to do without using class reference.
// Note that Delphi does not really recursively call the constructor.
Self.create (FALSE);
Self.AFTERCONSTRUCTION;
Except
// If there is any exception, Delphi automatically calls the sectors of the object.
Self.destroy;
end
Else
Self.create (FALSE);
Result: = Self;
END;
// The hidden code in the fabric is similar to this:
Procedure tsomething.destroy (deallocate: boolean);
Begin
IF deallocate thein
Self.beforeDestruction;
// Delphi is not really recursively calling the designer, but here is a place where the destructor truly acts.
Self.destroy (false);
IF deallocate thein
Begin
// Delphi doesn't really call CleanupInstance but call FreeInstance to do cleanup.
/ / If FreeInstance is covered, do not call Inherited FreeInstance, but CleanupInstance should be called
// to clean up the string, dynamic arrays, and variable type fields.
Self.cleanupinstance;
// Call freeInstance to release the memory occupied by the object.
Self.FreeInstance;
END;
END;
The Access level access level is similar to C and Java, Delphi provides different access level control mechanisms to determine if an object can be able to other objects, methods, and attributes, etc. The access level is divided into the following:
Private private methods can only be accessed by this type of own method and method, process, and function defined in the implementation section of the same unit. Delphi does not have a C -style friendly statement that does not have access control over the Java style package (Package Level Access). In the Delphi, the equivalent is to declare the package or friendly in the same unit, so that all classes of the unit can be accessed.
Protected protected methods can be accessed by this class and any method of derived class. The derived class can be in different units.
Public public disclosure methods do not have access restrictions. Any method, function, or process can access the part of the public declaration. The default access level is common unless you use a $ m compilation indicator.
The announcement of the published published published by Published is basically the same as the public statement, and the only difference is Delphi to save the runtime information. Some statements cannot be released; see Chapter 3. If the class or base class uses a $ m indicator, the default access level is published.
Tip: Delphi's IDE is unnamed in FORM, unnamed partial declaration fields and methods. Because TForm is inherited from TPERSISTENT, the $ m indicator is used in TPERSISTEN, so the first part of the access level is the published public. In other words, IDE declares fields and methods as published. When Delphi loads an FORM description file (.dfm file), it relies on published information to create the FORM object. The IDE depends on the declaration of the start of the FORM class. If you modify the part of the thing, there may be dangers that lead to the Ide's Form editor.
Automated automatic automatic statement is close to the disclosure, the only difference is that Delphi will save more runtime information to support OLE automation services. Automated statements have become old; you can turn to use Delphi's type library editor, but now they have retained some of them for backward compatibility. The next version of Delphi may completely eradicate these parts. Chapter III further elaborates a statement on automatic type.
The derived class can improve the level of accessibility attribute. This is achieved by re-declaring properties at the new access level (for example, the first protected change is disclosed). But you can't reduce the access level of an attribute, and you can't change whether a field or method is visible. You can override a virtual method or declare an access level in the same or higher level, but you can't reduce the access level.
Hidding a constructor hides the constructor
Sometimes, a class does not need to do common purposes, but just a secondary class of other classes. In this case, you may want the CREATE of the auxiliary class to be private or protected, but this requires skill. TOBJECT declares an open constructor: Create. Therefore, even if the auxiliary class constructor is private or protected, you can still call the Create constructor inherited from TOBJECT.
Although you can't change the access rights of the inherited Create constructor, you can also hide it through another disclosed constructor. Because if the derived constructor is called, an exception will be triggered. Such examples:
Type
TPUBLIC = Class;
TPRIVATEHELPER = Class
Private
// TPUBLIC is the only class that is allowed to call the true constructor
Constructor Create (Owner: Tpublic);
Overload; public
// Hide TOBJECT.CREATE to prevent accidental calls to try to create an instance of TPRIVATEHELPER
Constructor crete;
REINTROAD; OVERLOAD;
END;
TPUBLIC = Class
Private
Fhelper: tprivatehelper;
public
Constructor crete;
DESTRUCTOR DESTROY;
END;
Constructor tprivateHelper.create;
Begin
Raise Exception.create ('Programming Error')
END;
Constructor TPUBLIC.CREATE;
Begin
// This is the only place that tpriVateHelper can be created.
Fhelper: = tprivatehelper.create (Self);
END;
Properties property
Attributes look more like a field, but can play as the way. The property replaces the reader and the settings (sometimes referred to as getter and setter), but more motorized and powerful. Attributes are critical for Delphi's IDE, while we can also use properties in many other occasions.
The property is responsible for reading and setting the value of the attribute by a reader and a writer. Reader can be a field name, a selector of a collection field, or a method of returning to this property. Writer (Writer) can be a field name, a selector of a collection field or a way to set this property value. You can omit the writer, then this property is read-only attribute. Of course, you can omit the reader to create a write-written property, but use such a weird attribute will be restricted. At the same time, it is meaningless to omit the reader and writer, so Delphi does not allow you to do this.
Most readers and writers are field names or method names, you can also lead them to the part set field (records, and arrays). If a reader or writer points to an array element, the index of the array must be constant and the field cannot be a dynamic array. Records and arrays can nested, even you can use variable type records. Example 2-9 shows an extended rectangular type, similar to Windows's TRECT type, but it is a class, attributes and methods.
Example 2-9: Attribute readers and writers
TRECTEX = Class (TPERSIStent)
Private
R: TRECT;
Function GetHeight: Integer;
Function getWidth: integer;
Procedure setHeight (Const value: integer);
Procedure setWidth; Const Value: Integer;
public
Constructor Create (Const R: TRECT); OVERLOAD;
Constructor Create (Left, Top, Right, Bottom: Integer; Overload;
Constructor Create (Const Topleft, Bottomright: tpoint); OVERLOAD;
Procedure assign (Source: TPERSIStent); OVERRIDE;
Procedure Inflate (x, y: integer);
Procedure INTERSECT (Const R: TRECTEX);
Function isempty: boolean;
Function ISEQUAL (Const R: TRECTEX): Boolean;
Procedure Offset (X, Y: Integer);
Procedure Union (Const R: TRECTEX); Property Topleft: TPoint Read R.Topleft Write R.Topleft;
Property Bottomright: Tpoint Read R.BOTTOMRIGHT WRITE R.BOTTOMRIGHT;
Property RECT: TRECT READ R WRITE R;
Property Height: Integer Read GetHeight Write SetHeight;
Property Width: Integer Read GetWidth Write SetWidth
Published
Property Left: Integer Read R.Left Write R.Left Default 0;
Property Right: Integer Read R.right Write R.right Default 0;
Property top: Integer Read R.Top Write R.Top Default 0;
Property Bottom: Integer Read R.Bottom Write R.Bottom Default 0;
END;
Array Properties array properties
The array of properties is always related to the quantity, and with an array of features. An array type attribute cannot be released, but there are many other purposes. The index of the array can be any type and you can use a multi-dimensional array. For array properties, you must use readers and writers, because you have no way to map a array type property directly to a array-type field.
One of the array type properties of it can be specified as default. You can directly use object references and an array label to access this attribute without indicating that attribute names, as shown in Example 2-10.
Example 2-10: Using the default array properties
Type
Texample = Class
...
Property Items [i: integer]: Integer Read GetItem Write SetItem
Property Chars [C: Char]: Char Read GetChar Write setcha; DEFAULT
END;
VAR
Example: texample;
I: integer;
C: char;
Begin
EXAMPLE: = texample.create;
I: = example.Items [4]; // must explicitly specify the name of the attribute
C: = example ['x']; // Decade when the array type property
C: = example.Chars ['x']; // Effects As before
Parti Parti Partiii Partiv Partv Partvi More Articles