Many people in China regard Delphi as their preferred development tool. The reason is of course because Delphi provides developers with many features: object-oriented development, visual interface design, rich components, and multi-platform portability (new features of Delphi6).
But for beginners, object-oriented thinking may not be the biggest feeling that Delphi brings to them. The visual interface design and rich and diverse available components leave the most profound and unforgettable impression. The serious consequence of this is that beginners often only focus on the use of the existing VCL components provided by Delphi for a long time, while neglecting to think about the impact of object-oriented thinking on the entire Delphi The meaning contained in the component architecture system.
The following piece of code contains one of the most common mistakes that beginners often make. Although this mistake is not a grammatical error, it reveals that the user's object-oriented thinking needs to be strengthened:
var
Form1: TForm1;
implementation
{$R *.dfm}
PRocedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Form1.Caption); // <-- There are some problems with the use of Form1 here.
end;
There seems to be nothing wrong with this kind of code at first glance. However, the appearance of Form1 here is somewhat unreasonable. Obviously the code here is written to implement the ButtonClick method of TForm1, and Form1, as an instance of the TForm1 class, is actually written into the implementation of the class. Isn't there some conceptual confusion? It needs to be changed to conform to object-oriented thinking. It is also very simple and can be written in two ways:
1. ShowMessage(Self.Caption); // <-- This way of writing is very clear. The information to be shown is the Caption of the current instance of the class.
2. ShowMessage(Caption); // <-- The writing method here is the same as above, but the keyword Self is omitted;
The three core contents of object-oriented thinking are encapsulation, inheritance, and polymorphism. The problem exposed by the above example is the problem of encapsulation. Similar examples include:
var
Form1: TForm1;
...
var
Form2: TForm2;
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.Show; // <-- As a global variable, the use of Form2 here is also confusing.
end;
The above example may be more general. In most cases, in a project, TForm1 and TForm2 may only have one instance each, so such code can be considered passable. But in a strict sense, it does not meet the requirements of encapsulation. Refer to the following code:
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{Private declarations}
FNext: TForm;
public
{Public declarations}
property NextForm: TForm read FNext write FNext;
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if Assigned(FNext) then
TForm2(FNext).Show;
end;
end.
//The following is the content of the project file:
program Project1;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Form1.NextForm := Form2; // <-- Add this sentence to barely make the code meet the requirements of encapsulation
Application.Run;
end.
Pass the Form2 pointer to Form1 as an attribute of Form1. In this way, Form1 complies with the principle of encapsulation when calling! Of course, these codes are only to reflect the idea of encapsulation. In practice, you can decide whether you really want to implement it so thoroughly according to your personal habits. But this kind of thought should take root in the mind... (Unfinished, to be continued).
More articles