Oop Delphi中的消息处理程序方法忽略了它是;“私人”;
有两个类:Oop Delphi中的消息处理程序方法忽略了它是;“私人”;,oop,delphi,windows-messages,Oop,Delphi,Windows Messages,有两个类:TBaseClass和TDerivedClass,都是以单独的单元表示的 TBaseClass unit InhPriv.BaseClass; interface uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages; type TBaseClass = class(TWinControl) strict private procedure TheMethod(var msg: T
TBaseClass
和TDerivedClass
,都是以单独的单元表示的
TBaseClass
unit InhPriv.BaseClass;
interface
uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages;
type
TBaseClass = class(TWinControl)
strict private
procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
end;
implementation
procedure TBaseClass.TheMethod(var msg: TMessage);
begin
MessageBox(0, 'TBaseClass.TheMethod', 'IhheritedPrivateTest', 0);
end;
end.
unit InhPriv.DerivedClass;
interface
uses InhPriv.BaseClass, Winapi.Windows, Winapi.Messages, InhPriv.Messages;
type
TDerivedClass = class(TBaseClass)
public
procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
end;
implementation
procedure TDerivedClass.TheMethod(var msg: TMessage);
begin
inherited; //TBaseClass.TheMethod gets called!!!
MessageBox(0, 'TDerivedClass.TheMethod', 'IhheritedPrivateTest', 0);
end;
end.
tDelivedClass
unit InhPriv.BaseClass;
interface
uses Vcl.Controls, Winapi.Windows, Winapi.Messages, InhPriv.Messages;
type
TBaseClass = class(TWinControl)
strict private
procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
end;
implementation
procedure TBaseClass.TheMethod(var msg: TMessage);
begin
MessageBox(0, 'TBaseClass.TheMethod', 'IhheritedPrivateTest', 0);
end;
end.
unit InhPriv.DerivedClass;
interface
uses InhPriv.BaseClass, Winapi.Windows, Winapi.Messages, InhPriv.Messages;
type
TDerivedClass = class(TBaseClass)
public
procedure TheMethod(var msg: TMessage); message WM_CUSTOM;
end;
implementation
procedure TDerivedClass.TheMethod(var msg: TMessage);
begin
inherited; //TBaseClass.TheMethod gets called!!!
MessageBox(0, 'TDerivedClass.TheMethod', 'IhheritedPrivateTest', 0);
end;
end.
主机表单
TForm1 = class(TForm)
//.......
private
c: TDerivedClass;
//.......
end;
WM\u CUSTOM
定义为WM\u用户+1
调用方法
变体1:发送消息:
输出:
t基本类。方法tDelivedClass.TheMethod 变量2:直接调用方法: 输出: t基本类。方法
tDelivedClass.TheMethod CPU窗口 这是一个直接的方法调用
InhPriv.DerivedClass.pas.17: inherited; //TBaseClass.TheMethod gets called!!!
005B4880 8B55F8 mov edx,[ebp-$08]
005B4883 8B45FC mov eax,[ebp-$04]
005B4886 E87DFDFFFF call TBaseClass.TheMethod
Delphi文档说明:
当继承的之后没有标识符时,它引用与封闭方法同名的继承方法,或者,如果封闭方法是消息处理程序,则引用同一消息的继承消息处理程序
所以,并没有明确的词语表明将方法转换为消息处理程序会使Delphi编译器违反OOP原则
我可能错过了一些文档吗?考虑到消息处理程序是可以“调用”的,即使来自不同的进程,我不确定您在那里期望的是什么。在基类中限定私有方法的范围可以确保在子类中看不到它(除非两者在同一个单元中)。但是在您的描述中,您重新定义了
方法的范围,因此您可以在那里调用它。我想这是个小骗局。method
的private
作用域仅用于隐藏该方法,而不是使继承的
不起作用。如果我错了,请纠正我,因为这只是猜测导致此行为的原因。消息调度不关心方法可见性。如果tDelivedClass.TheMethod()
试图显式调用TBaseClass.TheMethod()
,由于可见性问题,该方法将无法工作。但是inherited
并不关心这一点。当我测试这一点(在Delphi XE2中)时,似乎有没有消息指令并不重要,但是调用简单的inherited而没有方法名这一事实才是重要的。这似乎绕过了严格的私人警卫。这是功能还是bug?