"Mastering Delphi 6" learning notes five
In a certain class, the variable declared in a class is not able to access casual access (by a statement of subcategory), which can be accessed by declaration. "Mastering Delphi 6" mentioned an uncommon trick:
// Unit2
TYPE TTEST = Class
protected
ProtectedVar: integer;
END;
// Unit1
Type
Tfake = Class (TTEST);
Procedure TFORM1.FormCreate (Sender: TOBJECT);
VAR
Test: TTEST;
Begin
Test: = TTEST.CREATE;
// Test.protacededVar: = 1; // not work!
Tfake (Test) .protacectedVar: = 1; // this works!
Test.free;
END;
Of course, you can also add code to TFake to implement the same function, but the advantage of the above method is that only one placeholder is required, without a class of derived a class that is ambiguous to modify a variable. This skill is rarely used in the actual situation, but since the author mentioned, it is still remembered.
The keyword used to declare the virtual function, as long as a virtual in C is OK, whether it is in the base class or derived class. But in Delphi, be sure to remember: use Virtual in the base class, using Override in the derived class. If you forget this, it will cause two consequences:
1. When compiling the program, you will get a "Method 'XXX'HIDES The Virtual Method Of Base Type' XXX '" (although the program can be run);
2. The polymorphism will not work properly. E.g,
Type
Tanimal = Class
Province; voice; virtual;
END;
TDOG = Class (tanimal)
Province; voice; virtual;
END;
IMPLEMentation
Procedure tanimal.voice;
Begin
ShowMessage ('Animal Voice');
END;
PROCEDURE TDOG.VOICE;
Begin
ShowMessage ('Dog Voice');
END;
Procedure TFORM1.FormCreate (Sender: TOBJECT);
VAR
A: tanimal;
Begin
A: = TANIMAL.CREATE;
a.voice;
a.free;
A: = TDOG.CREATE;
a.voice;
a.free;
END;
If you run this program, you will get two 'animal voice'. As long as you change the second Virtual in the statement to Override, you can get the right result: an 'Animal Voice' and a 'Dog Voice'.
In C , as long as the function in the base class is declared as Virtual, the same name function in the party will automatically become Virtual. So is the OVERRIDE keyword in Object Pascal? The author of "Mastering Delphi 6" explained this: Declaring Override indicates that you want to have a virtual Virtual function in the base class, so you can avoid common spelling errors. For example, in C , you wrote a Virtual function called FUNC in the base class and overloaded it in the derived class. Unfortunately, you accidentally spell FUNC into Fund. This error cannot be checked. When you point a base class pointer to a derived class, and I hope it automatically invokes the FUNC function of the derived class, it can actually only call the FUNC function that is called, and this class is difficult to find and exclude. Well, it seems that it seems to be reasonable.
Dynamic and Virtual
Dynamic and Virtual are not only the same, but the grammar of the statement is the same. They are only different in the internal mechanism. The implementation of the Virtual is implemented through the virtual method table (VTBL in VMT, Virtual Method Table, and C ), and each virtual function is occupied in the VMT in the class. One of the disadvantages of VMT is that regardless of whether there is a method in the reload base class in the class, it will not change the size of the VMT, so many positions in the VMT are actually repetitive, in a relatively large class library, It is necessary to waste a lot of memory. Dynamic's implementation method is different. It is not intended to point to the actual method through the VMT, but is achieved by the index, so that only the method of overloading in the derived class will occupy the actual entry, thereby saving memory. Dynamic is unfavorable because Dynamic's method (relative to VMT, Dynamic method table can be called DMT) is not necessarily the same in the base class and derived class, the same Dynamic Method entries is not necessarily Same, the Dynamic method must dynamically look up, and the call efficiency is low. In contrast, the entry position in the Virtual Method in the base class and derived class is always fixed, so the call is fast.
In short, Dynamic's advantage is that Virtual's disadvantages, Dynamic's disadvantages are the advantages of Virtual. You can decide to use virtual or Dynamic according to your needs. However, the difference between Dynamic and Virtual may be more important for programmers who write Application Framework or programs that are critical to those efficiency issues. For general applications, the virtual method will not be a lot, the size is not very large. It is generally enough to use virtual.
Object Pascal also supports Abstract Method, just add the Abstract keyword in the function declaration. Of course, only Virtual or Dynamic methods can be declared as abstract. Just differ in C , you can build an instance of Abstract Class, and call it Abstract method:
Type
TTEST = Class
PROCEUDRE F: Virtual; Abstract;
END;
Procedure TFORM1.FormCreate (Sender: TOBJECT);
VAR
Ttest;
Begin
T: = TTEST.CREATE;
T.f;
T.free;
END;
Although you will get a compiler warning constructing instance of 'xxxx' containing Abstract Method 'XXXX.XX', but the program can still run, just when T.f is called, a runtime exception will be generated. I don't know why Object Pascal is arranged so, in C , constructing an object containing an abstract method, no matter how it is successful. Why should Object Pascal add this? I do not know. You may not notice a small question about Abstract: Is there any problem with the code below?
Type
TTEST = Class
PROCEDURE F; VIRTUAL; ABSTRACT;
END;
TTEST2 = Class (TTEST)
Procedure f; Override;
END;
IMPLEMentation
Procedure ttest2.f;
Begin
inherited;
ShowMessage ('Test2.f!');
END;
Procedure TFORM1.FormCreate (Sender: TOBJECT);
VAR
T: TTEST2;
Begin
T: = TTEST2.CREATE;
T.f;
T.free;
END;
In Delphi 5, the above code generates an Abstract exception. The key is that inherited calls the base class's Abstract method. In Delphi6, the compiler can automatically identify this situation so that it will not cause problems. Obviously, this enhancement in Delphi 6 is more conducive to OO package characteristics, you can rest assured whether INHERITED use inherited without worrying about whether the basic class is abstract.