(Part 3 of "Putting Object-Oriented Thoughts Throughout - Talking about Delphi Development")
The first two articles discussed topics related to encapsulation. Here, I want to talk to you about inheritance and polymorphism.
Inheritance and polymorphism are closely related. Object Pascal introduces a polymorphic mechanism called overload. Its idea has little to do with object-oriented and will not be discussed here. Polymorphism, which is closely related to object-oriented thinking, is what we focus on.
Polymorphism relies on the concepts of abstract methods and virtual methods, and is also closely related to inheritance. It is thought that we often define some underlying objects and then define some of their implementations as abstract, which means that we only define the interface without defining specific implementation details. Following this idea, we will also define multiple derived (inherited) objects, in which details that have not been implemented in the ancestor class are actually implemented. This makes the underlying class we defined previously polymorphic. The advantage of this mechanism is that when we use these classes, we only need one set of code to complete multiple functions. The only thing that needs to change is the part that creates an instance of the object.
Observe a class like this:
TStream = class(TObject)
…
public
function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
…
end;
The virtual and abstract reserved words indicate that the Read and Write methods are pure virtual functions. This shows that the TStream class cannot really be used (instances of this class cannot be created). It is just a class similar to an interface, which defines the basic functions that the TStream class should have and need to handle. And it also stipulates that other classes derived from the TStream class must implement functions (such as Read and Write, etc.).
For example, TFileStream implements the TStream class in the form of disk file applications; while TMemoryStream implements the TStream class in the form of memory applications. Now suppose there is a class TMyClass that provides a SaveToStream method:
TMyClass = Class(TObject)
PRocedure SaveToStream(Stream: TStream);
end;
Then applying the idea of polymorphism, you can have code like this:
var
strm: TStream;
MyClass: TMyClass;
begin
strm := TFileStream.Create('abc.txt'); // ß The real instance type of Stream here is TFileStream
MyClass := TMyClass.Create;
MyClass.SaveToStream(strm);
…..
end;
To store the contents of MyClass in memory, just change
strm := TFileStream.Create('abc.txt');
for:
strm := TMemoryStream.Create;
That’s it.
The use of polymorphism requires two aspects of work. One is, of course, that polymorphism is taken into account in the class structure and can provide intermediate classes (abstract classes) that implement certain functions; the other is to know how to use these intermediate classes. This The work is reflected in defining some procedures and parameters of functions.
Another very important point, I would like to remind everyone that class planning is very important. In the era of object-oriented programming, the class framework determines the program framework to a large extent and determines the success or failure of software development. A clear and hierarchical class architecture not only facilitates functional division and expansion, but also makes code maintenance easier. Among these, applying the ideas of inheritance and polymorphism, introducing abstract classes, and introducing intermediate classes is a more preferable method.
The following lists some of the abstract classes and concrete classes provided in Delphi:
concrete class derived from abstract class
TStream TFileStream, TMemoryStream;
TCustomIniFile TIniFile, TMemIniFile, TRegistryIniFile;
TStrings TStringList, TMemoStrings, TListBoxStrings;
There are many more, waiting for you and me to discover. The most commonly used one here is TStream, and what surprises me the most is TCustomIniFile. Its TRegistryIniFile allows you to access the registry in the same way as IniFile! This allows me to use a set of codes to implement the functions of writing the registry and writing Ini files. Although the technology involved is simple, its significance is extraordinary!
(Unfinished, to be continued)
More articles