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。在类构造函数中一定要调用基类构造函数。

  • 相关阅读:
    30分钟掌握ES6/ES2015核心内容[上和下], 不错的说
    根据HTML5 获取当前位置的经纬度【百度地图】【高德地图】
    vue2 入门 教程 单页应用最佳实战[*****]
    JavaScript如何比较两个数组的内容是否相同【转】
    推荐下:开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !
    浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异[转]
    原生JavaScript插件开发[转]
    性能监控之Spotlight
    Jmeter(三十五)聚合报告
    Jmeter(三十四)Jmeter-Question之“Cookie获取”
  • 原文地址:https://www.cnblogs.com/pchmonster/p/2308119.html
Copyright © 2011-2022 走看看