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.对象是有类型的,不同的对象是属于不同的类型.
Delphi中静态方法重载还是覆盖的讨论的更多相关文章
- C++中的虚继承 & 重载隐藏覆盖的讨论
虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...
- C++中的重载隐藏覆盖&&JAVA中的重载覆盖&&多态
class 类继承默认是private, struct 默认继承是public C++中的隐藏: 只要派生类中出现和基类一样的函数名,基类中的函数就会被派生类中的函数给隐藏(如果派生类和基类中的函数名 ...
- C++中的重载、覆盖、隐藏
前几天面试时被问及C++中的覆盖.隐藏,概念基本答不上来,只答了怎么用指针实现多态,也还有遗漏.最终不欢而散.回来后在网上查找学习了一番,做了这个总结.其中部分文字借用了别人的博客,望不要见怪.引用的 ...
- C++中overload(重载),override(覆盖),overwrite(重写/覆写)的区别
#include <cstdio> #include <cstdlib> class Base { public: #pragma region MyRegion1 //函数重 ...
- c++中的重载、覆盖和隐藏
1 重载发生在同一个类内部. 同一个类内部,具有相同的函数名,但是参数列表不同,那么就是重载.因为c++编译器编译时,将函数名和函数列表一起对函数进行了重命名. 2 覆盖和隐藏发生在子类和父类之间. ...
- java中重载、覆盖和隐藏三者的区别分析
重载:方法名相同,但参数不同的多个同名函数 注意:1.参数不同的意思是参数类型.参数个数.参数顺序至少有一个不同 2.返回值和异常以及访问修饰符,不能作为重载的条件(因为对于匿名调用,会出现歧义,eg ...
- DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)
函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...
- 四. Java继承和多态3. 继承中的方法的覆盖和重载
在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类 ...
- java中方法的重载和覆盖分别要满足的条件
1.重载:遵循“两同三不同” 两同:同一个类中的同名方法 三不同:形参的类型,个数,顺序不同 特别提醒: 返回值不同构不能方法重载 形参名称不同构不成方法重载 2.覆盖(重写)的要求 子类方法的名称, ...
随机推荐
- mybatis 插件安装与使用
安装 1.在MarketPlace 中搜索 MyBatipse 安装 2.下载MyBatipse 插件 使用 ......
- Kerberos 互信免登陆
第一步:机器加互信 将机器A的Kerberos name加到机器B的~/.k5login中,同时将机器B的Kerberos name加到机器A的~/.k5login中 例如:host/bjm6-193 ...
- java学习笔记整理
java知识模块:1.基础知识,数组,字符串,正则表达式:2.类和对象,接口,继承,多态,抽象类,内部类,泛型,java常用类库.3.异常处理: 4.IO: 5.事件处理: 6.多线程: 7 ...
- 把图片上的文字转换成word文字?
转换后的文字不是很如意,但是免费方便. 1.打开Office办公软件自带的OneNote工具.随便新建一个笔记页面,以方便我们接下来的操作. 2.插入图片.在菜单栏里点击[插入],选择插入[图片],找 ...
- kafka NoNode错误
报错 bin/kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper localhost:2181 --group=app-t ...
- NumPy 从数值范围创建数组
NumPy 从数值范围创建数组 这一章节我们将学习如何从数值范围创建数组. numpy.arange numpy 包中的使用 arange 函数创建数值范围并返回 ndarray 对象,函数格式如下: ...
- Flask中的蓝图(BluePrint)、
蓝图 1.初识Flask蓝图(BluePrint) 创建一个项目然后将目录结构做成: user.py中的内容 from flask import Blueprint, render_template ...
- Python+Selenium学习--操作测试对象
场景 前面已经讲解了如果定位对象,定位之后需要对这个对象进行操作.是鼠标点击还是键盘输入,取决于我们定位的对象缩支持的操作. webdriver中比较常用的操作元素的方法有下面几个: clear ...
- 填坑专记-手脱FSG壳
妈呀,脱FGS壳真的是坎坷颇多,多亏吾爱破解前辈们的帮忙.我一定要记录下来,省的以后再无法解决. 已经查看是FSG壳了.找到入口也容易了.重点就是脱壳并修复好它. 脱壳 OEP为: 使 ...
- 【php 之获得当前日期以及比较日期大小】
首先看一个例子: $currentTime = date('Y-m-d H:i'); // 获得当前时间 $timer = $searchDated . ' ' . $results['ctrip'] ...