• 虚拟方法virtual的用法


    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;

    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;

      TFather = class
      public
        procedure Fa; // virtual;
      end;

      TChild = class(TFather)
      public
        procedure Fa; // override;
        procedure Ca;
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    { TChild }

    procedure TChild.Ca;
    begin
      ShowMessage('Childer');
    end;

    procedure TChild.Fa;
    begin
     // inherited;
    end;

    { TFather }

    procedure TFather.Fa;
    begin
      ShowMessage('Father');
    end;

    procedure TForm1.Button1Click(Sender: TObject);              // C->F
    var
      F: TFather;
    begin
      F := TChild.Create;
      F.Fa;
     // F.Ca; //编译不过去
    end;

    procedure TForm1.Button2Click(Sender: TObject);              // C(F)
    var
      F: TFather;
    begin
      F := TFather.Create;
      TChild(F).Fa; //***  声明方法时,如果不用 virtual 和 override 关键字修饰的话
                    //***  那么在子类实现时要手动的调用 inherited 才可以正确调用父
                    //***  类实现的方法,但是如果使用了 virtual 和 override 的话,
                    //***  则可以不用手动的调用 inherited 也能正确调用(即当按Ctrl+C
                    //***  时会自动添加inherited。

      TChild(F).Ca; //虽然创建的是父类,但是强制转换后(重新设定对象范围)可以调用。
                    //但是不确定是否会有意外的错误发生。
                    //如果使用了关键字override,编译器会使用晚帮定,即到运行是根据实
      //际的对象来决定调用父类方法还是子类方法
      //换句话说就是使用了关键字的话,强制转换将不起作用。(起到的作用
      //只是检测到父类中是否有此方法了,有可以调用,但是调用的还是子类
      //的方法,要是没有就根本不能调用)
    end;

    procedure TForm1.Button3Click(Sender: TObject);              // F(C)
    var
      C: TChild;
    begin
      C := TChild.Create;
      TFather(C).Fa;
      //TFather(C).Ca;     //编译不过去
    end;

    end.

  • 相关阅读:
    Java 9 模块解耦的设计策略
    Spring Data JPA 事务锁
    如何配置Spring Boot Tomcat
    Spring Cloud Turbine
    Spring Boot 测试时的日志级别
    Spring Boot中使用RSocket
    构造函数
    递归函数的使用
    有序数列的二分搜索
    Java第一次代码作业汇总
  • 原文地址:https://www.cnblogs.com/spiritofcloud/p/3898363.html
Copyright © 2020-2023  润新知