zoukankan      html  css  js  c++  java
  • 初探Object Pascal的类(十)

    覆盖方法

    先来讨论下虚拟方法,还是以TAirplane为例,注意到TakeOff方法在TAirplane类中是虚拟方法(TakeOff方法的声明的结尾有virtual关键字),TakeOff方法由SendMessage调用,并响应MsgTakeOff消息,如果它的派生类TMilitaryPlane类没有提供自己的TakeOff方法,基类TAirplaneTakeOff方法就会被调用。由于TMilitaryPlane类提供了一个TakeOff方法,这样就调用TMilitaryPlane类的TakeOff方法,而不调用基类的方法。

    在派生类中代替一个基类的方法称作为覆盖方法

    为了能够做覆盖工作,此方法的特征必须与基类中的方法严格匹配,也就是说,其返回类型、方法名和参数表都必须要与基类方法一致。另外,派生类中的方法必须用关键字override声明。

    Note

    Object Pascal也有一种动态方法,就大部分程序员来说,对待动态方法与对待虚拟方法是一样的。其不同之处在于虚拟方法指针存放在类的虚拟方法表(VMT,Virtual Method Table)中。

    目前是否理解这种不同并不重要,这里只是让大家知道存在动态方法,以免在翻阅Delphi例子和VCL源代码时遇到它,在大部分情况下,在程序中处理动态方法与处理虚拟方法一样。

    用覆盖方法代替基类方法,或者用覆盖方法来加强基类方法。以TakeOff方法为例,若想要完全代替TAirplane类提供的TakeOff方法,就可以覆盖它,下面提供了所需要的代码:

    procedure TMilitaryPlane.TakeOff(Dir: Integer);
    begin
      { 新代码}
    end;

    如果想要继承基类的功能,并还要在此基础上增加一些功能,就应该先调用基类方法,然后增加新代码。调用基类的方法用关键inherited,例如:

    procedure TMilitaryPlane.TakeOff(Dir: Integer);
    begin
      { 首先调用基类的TakeOff方法}
      inherited TakeOff(Dir);
      { 新代码}
    end;

    通过调用基类方法,可以得到写在基类中方法的原始性能,然后可在调用基类方法之前或之后增加新代码来加强基类方法。注意TakeOff方法声明在TAirplane类的protected段,若是在private段,它将不能工作,因为即使是派生类也不能存取其祖先类的私有成员,通过设置TakeOff方法为保护的(protected),从而把它从外界隐藏起来,但其派生类仍可以存取。

    Note

    对于私有存取(private)和保护存取(protected)规则有一个例外,如果派生类声明在基类的同一单元中,那么基类的私有字段和方法对派生类都是有效的,但若派生类声明在独立的单元中,那么只有基类的保护字段和方法对派生类是有效的。

    当从另一个派生类时,必须确保调用基类的构造函数,这样才能使所有的祖先类作正确的初始化,调用基类构造函数也要用关键则inherited,在看看TAirplane类的构造函数:

    constructor TAirplane.Create(AName: string; AKind: Integer);
    begin
      { 初始化过程,设置飞机名称、类型和升限}
      inherited Create;
      Name := AName;
      Kind := AKind;
      Status := OnRamp;
      case Kind of
        Airliner: Ceiling := 35000;
        Commuter: Ceiling := 20000;
        PrivateCraft: Ceiling := 8000;
      end;
    end;

    注意调用基类的Create构造函数就是保证正确的创建此类。当声明类时,如果没有明确声明基类,那么其基类自动为TObject。在类构造函数中一定要调用基类构造函数。

  • 相关阅读:
    Leetcode 811. Subdomain Visit Count
    Leetcode 70. Climbing Stairs
    Leetcode 509. Fibonacci Number
    Leetcode 771. Jewels and Stones
    Leetcode 217. Contains Duplicate
    MYSQL安装第三步报错
    .net 开发WEB程序
    JDK版本问题
    打开ECLIPSE 报failed to load the jni shared library
    ANSI_NULLS SQL语句
  • 原文地址:https://www.cnblogs.com/pchmonster/p/2308119.html
Copyright © 2011-2022 走看看