} } }

    Delphi中静态办法重载还是覆盖的评论辩论

    添加时间:2013-7-2 点击量:

    Delphi中静态办法重载还是覆盖的评论辩论


    新人进修Delphi的时辰,轻易搞不懂的一个题目,当子类办法和基类办法同名,并且参数也一样的时辰,叫做什么呢?是覆盖,还是重载呢?


     


    答案是隐蔽父类办法。


     


    一般我们的懂得重载是同名,不合参数的同一个类里面实现,


    或者父类和子类办法同名,参数不合,子类必须有overide关键字,默示重载办法。


     


    也就是说重载必须有overload润饰;


     


    覆盖呢?覆盖必须有override批改;


     


    不然同名,同参数就是隐蔽办法。


    =================================================================


    下面是笔者本身的法度,您可以测验测验一下。


     


    program Project2;


     


    {¥APPTYPE COLE}


     


    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+EAX2-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.对象是有类型的,不合的对象是属于不合的类型.


     


    分享到: