zoukankan      html  css  js  c++  java
  • 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.对象是有类型的,不同的对象是属于不同的类型.

     

  • 相关阅读:
    GetEnumName 枚举名称 字符串
    拖拽文件
    小米手机Root 刷机
    微软语言 中文 英文 中英文
    MTP
    MD5加密算法全解析
    ORA-28000: the account is locked
    HTTP状态码
    HTTP 消息结构
    @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  • 原文地址:https://www.cnblogs.com/stevenlaz/p/3166406.html
Copyright © 2011-2022 走看看