Delphi中静态方法重载还是覆盖的讨论
Delphi中静态方法重载还是覆盖的讨论
新人学习Delphi的时候,容易搞不懂的一个问题,当子类方法和基类方法同名,并且参数也一样的时候,叫做什么呢?是覆盖,还是重载呢?
答案是隐藏父类方法。
一般我们的理解重载是同名,不同参数的同一个类里面实现,
或者父类和子类方法同名,参数不同,子类必须有overide关键字,表示重载方法。
也就是说重载必须有overload修饰;
覆盖呢?覆盖必须有override修改;
否则同名,同参数就是隐藏方法。
=================================================================
下面是笔者自己的程序,您可以尝试一下。
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
type tclassa=class
private
age :Integer;
public
function getage:integer; //静态方法
function getDat:integer; //静态方法
end;
tclassb=class(tclassa)
private
public
function getdat:integer; //隐藏静态方法
function getage:Integer; //隐藏静态方法
end;
{ tclassa }
function tclassa.getage: integer;
begin
age := 1;
result := age;
end;
function tclassa.getDat: integer;
begin
result := 3;
end;
{ tclassb }
function tclassb.getage: Integer;
begin
Result := 1+ inherited getage();
end;
var a:tclassa;
b:tclassb;
function tclassb.getdat: integer;
begin
result := 1 + inherited getdat();
end;
begin
a := tclassa.Create;
b := tclassb.Create;
Writeln(a.getage());
Writeln(b.getage());
Writeln(a.getdat());
Writeln(b.getdat()); // 调用的是子类的隐藏后的静态方法
readln;
readln;
a.free;
b.free;
{ TODO -oUser -cConsole Main : Insert code here }
end.
我们可以看到隐藏了父类方法之后,还是可以调用父类同名方法的。这就和覆盖是相似的。
参考资料
=================================
Delphi面向对象方法的分类以及覆盖隐藏和重载
<6> 方法的分类
按用途分 普通方法,构造方法,析构方法, 类方法,消息处理方法
按运行绑定机制分:静态方法,虚方法,动态方法,[注意此处的静态方法不是所谓的class method 而是普通的方法 ,静态是指静态编译]
关于析构方法,最好是用名字destroy ,这样可以使用Free方法,而不要直接调用destroy方法.
Free方法会先判断对象变量是否为nil.
procedure TObject.Free;
begin
if Self <> nil then
Destroy;
end;
消息处理方法的例子:
procedure WMChar(var message:TWMChar);message WM_CHAR;
问题来了.为什么在一个Control中声明了消息处理方法,就能调用此消息处理方法呢,这里涉及到
TObject 中Dispatch方法的秘密,我暂时没有看懂.留作以后继续学习
先给出Dispatch的源码.
procedure TObject.Dispatch(var Message);
asm
PUSH ESI
MOV SI,[EDX]
OR SI,SI
JE @@default
CMP SI,0C000H
JAE @@default
PUSH EAX
MOV EAX,[EAX]
CALL GetDynaMethod
POP EAX
JE @@default
MOV ECX,ESI
POP ESI
JMP ECX
@@default:
POP ESI
MOV ECX,[EAX]
JMP DWORD PTR [ECX] + VMTOFFSET TObject.DefaultHandler
end;
GetDynaMethod的方法源码如下
procedure GetDynaMethod;
asm
{ -> EAX vmt of class }
{ SI dynamic method index }
{ <- ESI pointer to routine }
{ ZF = 0 if found }
{ trashes: EAX, ECX }
PUSH EDI
XCHG EAX,ESI
JMP @@haveVMT
@@outerLoop:
MOV ESI,[ESI]
@@haveVMT:
MOV EDI,[ESI].vmtDynamicTable
TEST EDI,EDI
JE @@parent
MOVZX ECX,word ptr [EDI]
PUSH ECX
ADD EDI,2
REPNE SCASW
JE @@found
POP ECX
@@parent:
MOV ESI,[ESI].vmtParent
TEST ESI,ESI
JNE @@outerLoop
JMP @@exit
@@found:
POP EAX
ADD EAX,EAX
SUB EAX,ECX { this will always clear the Z-flag ! }
MOV ESI,[EDI+EAX*2-4]
@@exit:
POP EDI
end;
<7> 方法的覆盖,隐藏和重载
覆盖是override ,重载是overload;
隐藏是子类中的方法和父类的方法同名,而且参数相同,没有override修饰符,则子类的方法就隐藏父类的方法.
Example:
...
TChineseMan = class(TMan)
procedure SayHello(words:string); //打招呼
end;
....
procedure TChineseMan.SayHello(words: string);
begin
ShowMessage('TChinese Man SayHello '+words);
end;
...
procedure TForm1.Button1Click(Sender: TObject);
var
APerson:TMan;
AChinesePerson:TChinesePerson;
begin
APerson:=TChineseMan.Create;
APerson.SayHello('是一名中国人');
//注意了此处调用的是父类的TMan.Sayhello方法
//
ChinesePerson:=TChinesePerson.Create;
ChinesePerson.SayHello('是一名中国人'); //此时调用的是TChineseMan.sayHello
//如果想要APerson调用TChineseMan.sayHello方法 应该采取强制类型转换,强制类型转换其实就是对象框架的范围调整
TChinesePerson(APerson).SayHello('是一名中国人'); //此时调用的是TChineseMan.sayHello
end;
<8> 可见性
Delphi中四种类成员的保护方式:published,public,protected,private;
published,public 是可以最大访问,protected是对之类是可见的,private是对子类不可见
另外对象变量如果与其类的声明在同一个单元中,则private,protected失去作用,全部都是public
有点类似C++中友元的概念
Example
类TMan和此函数在同一个单元
procedure TForm1.Button1Click(Sender: TObject);
var
APerson:TMan;
begin
TMan.Sing;
APerson.FAge:=10;//虽然FAge是private ,但是此处确可以访问
APerson:=TMan.Create;
APerson.Name:='小李';
APerson.SayHello(' 是一名中国人');
end;
<<Delphi面向对象编程>>读书笔记之二
<1>什么是对象
A.对象是一组相关代码和数据的组合.面向对象程序设计中,过程(函数)被成为方法,数据被称做属性(注意此处的属性和类中property不是一回事)
B.对象之间可以通过发送消息请求而互相联系,一个消息通常由三部分组成:接收对象的名字,对象成员的名字(方法和property),对象成员的参数
C.对象是有类型的,不同的对象是属于不同的类型.
转载于:https://www.cnblogs.com/stevenlaz/p/3166406.html
Delphi中静态方法重载还是覆盖的讨论相关推荐
- C++中的虚继承 重载隐藏覆盖的讨论
虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...
- C++中的重载、覆盖、隐藏对比
1.重载.重写(覆盖).隐藏三者概念解释 重载(overload):同一个可访问区域内被声明的几个具有不同参数列(参数的类型.个数.顺序不同)的同名函数.根据参数列表,最终确定调用哪个函数,重载不关心 ...
- 谈谈C++继承中的重载,覆盖和隐藏
写正题之前,先给出几个关键字的中英文对照,重载(overload),覆盖(override),隐藏(hide).在早期的C++书籍中,可能 翻译的人不熟悉专业用语(也不能怪他们,他们不是搞计算机编程的 ...
- php继承和重载区别,php继承中方法重载(覆盖)的应用场合
php继承中方法重载(覆盖)的应用场合 发布于 2015-02-23 17:57:23 | 91 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...
- 【原创】Performanced C++ 经验规则 第五条:再谈重载、覆盖和隐藏
第五条:再谈重载.覆盖和隐藏 在C++中,无论在类作用域内还是外,两个(或多个)同名的函数,可能且仅可能是以下三种关系:重载(Overload).覆盖(Override)和隐藏(Hide),因为同名, ...
- C++学习笔记-----继承体系中函数的重载,覆盖和隐藏的区别
1.重载,在同一个作用域中定义的同名不同参的一些函数为重载. 2.隐藏,若在基类中定义了某一non_virtual函数,在派生类重存在同名函数(不需要参数列表相同),基类的该函数在派生类中是不可见的, ...
- (转)剖析Delphi中的构造和析构
剖析Delphi中的构造和析构 1 Delphi中的对象模型: 2 1.1 对象名表示什么? 2 1.2 对象存储在哪里? 2 1.3 对象中存储了什么?它们是如何存储的? 3 2 构造函数与创建对象 ...
- Delphi中SendMessage使用说明
Delphi中SendMessage使用说明 SendMessage基础知识 函数功能:该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而函数Po ...
- DELPHI 中 Window 消息大全使用详解
Window 消息大全使用详解 导读: Delphi是Borland公司的一种面向对象的可视化软件开发工具. Delphi集中了Visual C++和Visual Basic两者的优点:容易上手.功能 ...
最新文章
- 二维随机变量期望公式_MIT 6.041 概率论笔记 离散随机变量(二)
- (chap8 确认访问用户身份的认证) DIGES认证(摘要认证)
- Linux-2.6.20的cs8900驱动分析
- 大道至简—GO语言最佳实践
- Python统计分析--- 5.统计法与随机梯度下降(SGD)
- Black and white
- 一分钟理解三次握手和四次挥手
- C#中的委托是什么?事件是不是一种委托?
- 二叉搜索树的第k个节点
- Thingworx入门学习
- pbootcms模板,pbootcms模板程序,pboot响应式模板
- YOLO Air:科研改进论文推荐 | 改进组合上千种搭配,包括Backbone,Neck,Head,注意力机制,适用于YOLOv5、YOLOv7、YOLOX等算法
- php 加号转义,URL中加号(+)转义问题
- react-navigation v6 中文极速版
- xml分页php采集,海洋cms自动采集脚本可分页
- python模糊图像判断
- JS- 数字自增动画
- 开关电源和普通电源有什么区别?
- 电信新势力,TIP/CORD能颠覆电信设备商吗?
- UWP 和 WPF 对比