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中静态方法重载还是覆盖的讨论的更多相关文章

  1. C++中的虚继承 & 重载隐藏覆盖的讨论

    虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...

  2. C++中的重载隐藏覆盖&&JAVA中的重载覆盖&&多态

    class 类继承默认是private, struct 默认继承是public C++中的隐藏: 只要派生类中出现和基类一样的函数名,基类中的函数就会被派生类中的函数给隐藏(如果派生类和基类中的函数名 ...

  3. C++中的重载、覆盖、隐藏

    前几天面试时被问及C++中的覆盖.隐藏,概念基本答不上来,只答了怎么用指针实现多态,也还有遗漏.最终不欢而散.回来后在网上查找学习了一番,做了这个总结.其中部分文字借用了别人的博客,望不要见怪.引用的 ...

  4. C++中overload(重载),override(覆盖),overwrite(重写/覆写)的区别

    #include <cstdio> #include <cstdlib> class Base { public: #pragma region MyRegion1 //函数重 ...

  5. c++中的重载、覆盖和隐藏

    1 重载发生在同一个类内部. 同一个类内部,具有相同的函数名,但是参数列表不同,那么就是重载.因为c++编译器编译时,将函数名和函数列表一起对函数进行了重命名. 2 覆盖和隐藏发生在子类和父类之间. ...

  6. java中重载、覆盖和隐藏三者的区别分析

    重载:方法名相同,但参数不同的多个同名函数 注意:1.参数不同的意思是参数类型.参数个数.参数顺序至少有一个不同 2.返回值和异常以及访问修饰符,不能作为重载的条件(因为对于匿名调用,会出现歧义,eg ...

  7. DELPHI语法基础学习笔记-Windows 句柄、回调函数、函数重载等(Delphi中很少需要直接使用句柄,因为句柄藏在窗体、 位图及其他Delphi 对象的内部)

    函数重载重载的思想很简单:编译器允许你用同一名字定义多个函数或过程,只要它们所带的参数不同.实际上,编译器是通过检测参数来确定需要调用的例程.下面是从VCL 的数学单元(Math Unit)中摘录的一 ...

  8. 四. Java继承和多态3. 继承中的方法的覆盖和重载

    在类继承中,子类可以修改从父类继承来的方法,也就是说子类能创建一个与父类方法有不同功能的方法,但具有相同的名称.返回值类型.参数列表. 如果在新类中定义一个方法,其名称.返回值类型和参数列表正好与父类 ...

  9. java中方法的重载和覆盖分别要满足的条件

    1.重载:遵循“两同三不同” 两同:同一个类中的同名方法 三不同:形参的类型,个数,顺序不同 特别提醒: 返回值不同构不能方法重载 形参名称不同构不成方法重载 2.覆盖(重写)的要求 子类方法的名称, ...

随机推荐

  1. 微信小程序--分享报错(thirdScriptError Cannot read property 'from' of undefined;at pages/index/index page onShareAppMessage function TypeError: Cannot read property 'from' of undefined)

    分享功能: onShareAppMessage: function (res) { if (res.from === 'button') { // 来自页面内转发按钮 console.log(res. ...

  2. windows下配置pymysql

    可以直接pip安装 pip install pyMysql

  3. echarts 树图

    1 事件:事件绑定,事件命名统一挂载到require('echarts/config').EVENT(非模块化为echarts.config.EVENT)命名空间下,建议使用此命名空间作为事件名引用, ...

  4. NCB之taxonomy系列

    1.taxonomy之简介 生物分类学是研究生物系统的一种强有力的组织原则.遗传.共同遗传的同源性以及在确定功能时保护序列和结构,这些都是生物学的中心思想,直接关系到任何一组生物体的进化史.因此,分类 ...

  5. thymeleaf 在js中获取message信息或获取后台属性

    <script th:inline="javascript"> /*<![CDATA[*/ [[#{message1}]] [[${abc}]] /*]]> ...

  6. CSS垂直翻转/水平翻转提高web页面资源重用性

                    /*水平翻转*/ .flipx {     -moz-transform:scaleX(-1);     -webkit-transform:scaleX(-1);   ...

  7. Ant 使用指南 与 知识汇总

    一.Ant是什么?        Ant是一种基于Java和XML的build工具.它可以帮助我们将项目开发过程中需要完成的各种步骤组织起来,通过一个简易的方式来构建整个项目.Ant究竟能做什么呢?这 ...

  8. Mac 动态库加载不上

    OC xcode can't found xxx.dylib 1 targer- build phase :link binary with library添加动态库 注意不要将后边的选项选成opti ...

  9. 【校招面试 之 C/C++】第33题 C++ 11新特性(四)之STL容器

    C++ 11新增array.forward_list(单链表).unordered_set.unordered_map集中容器.

  10. swift - 自定义tabbar按钮的操作

    1.自定义tabbar按钮 只能 present出来VC 或者 nav. 因为它本身 没有导航控制器, 只有在tabbar 的根导航控制器的 VC 才能push