当前位置:首页 > Windows程序 > 正文

Delphi面向对象学习随笔三:overload与override

2021-03-16 Windows程序

作者:巴哈姆特
(转载请注明出处并保持完整)
    首先,我想单独说明一下overload,为什么呢?因为overload和对象化关联不大,所以,我感觉单独提出来说明比较好。
    我们都知道,在Pascal语法规则中,同一个UNIT里是不能存在两个同名的函数的,例如:

function func(): Boolean;

function func(const x: Char): Boolean;

 

这样是会出语法错误的,原因是因为标识符规则限制。但是问题出来了,如果我们需要几个功能相似但是参数不同的函数,那么根据标识符规则,我们就必须定义几个不同名,但是功能相同或相似的函数。
    如,假设我需要一个函数,要实现返回参数一减去参数二后的值,那么我们就将这样定义函数:

function SubInt(const Value1, Value2: Integer): Integer;

functino SubReal(const Value1, Value2: Real): Real;

function SubDouble(const Value1, Value2: Double): Double;

 

implementation

 

function SubInt(const Value1, Value2: Integer): Integer;

begin

  Result:= Value1 - Value2;

end;

 

functino SubReal(const Value1, Value2: Real): Real;

begin

  Result:= Value1 - Value2;

end;

 

function SubDouble(const Value1, Value2: Double): Double;

begin

  Result:= Value1 - Value2;

end;

 

我们可以看到,这三个函数除了参数名不同外,实现部分是一样的,这为程序的一致性带来了一定的麻烦。如果能定义一个同名函数来处理这几种不同情况的话,便有利于代码的重用,也有利于我们的记忆。这时我们就可以用overload来完成我们的需求了。

function Sub(const Value1, Value2: Integer): Integer; overload;

function Sub(const Value1, Value2: Real): Real; overload;

function Sub(const Value1, Value2: Double): Double; overload;

 

implementation

 

function Sub(const Value1, Value2: Integer): Integer;

begin

  Result:= Value1 - Value2;

end;

 

function Sub(const Value1, Value2: Real): Real;

begin

  Result:= Value1 - Value2;

end;

 

function Sub(const Value1, Value2: Double): Double;

begin

  Result:= Value1 - Value2;

end;

 

由此可见,名字相同而参数的数据类型或数量不同的函数,称之为overload函数。这是因为编译器在编译时不仅使用了函数名的信息,还使用了参数类型和数量的信息,通过组合这些信息可以确定分配地址时需要的唯一标识,通常我们叫他signature。例如:

Sub(1, 2);     // 调用的是 function Sub(const Value1, Value2: Integer): Integer;

Sub(1.0, 2.0); // 调用的是 function Sub(const Value1, Value2: Real): Real;

 

这里要说明一下,如果是同名函数,并且参数也相同,只是返回值不同的话,是不能实现overload的。

对于overload的说明就到这里吧,下面我们来说override:
    前面我说过,在派生一个新类的时候,首先会继承父类中的所有可继承部分,那么就意味着,默认情况下,父类所有的非私有

部分的类成员或方法都已经包含在新类中。
    但是,如果我们要为类的一个方法添加新的代码而又不希望重写父类方法中原有功能的话,我们可以用override来实现方法的覆盖,并用inherited来继承(或者可以说调用)父类方法中的方法功能:

type

  TBaseClass = class(TObject)

    // 定义一个新的父类

  protected

    FMessage: string;

  public

    constructor Create();    // 构造方法

    procedure MessageBox(); virtual; // 显示字符串

  end;

 

  TChildClass = class(TBaseClass)

    // 定义一个TBaseClass的派生类

  public

    procedure MessageBox(); override; // 重载父类中的方法

  end;

 

implementation

 

constructor TBaseClass.Create;

begin

  inherited Create();   // 继承父类中的构造方法Create

  FMessage:= ClassName; // 初始化信息字符串为类名

end;

 

procedure TBaseClass.MessageBox;

begin

  ShowMessage(FMessage); // 显示字符串

end;

 

procedure TChildClass.MessageBox;

begin

  FMessage:= FMessage + FMessage;

  inherited MessageBox(); // 继承父类中原有MessageBox方法的原有功能

end;

 

好,我们可以编写一个简单的例子来调用一下:

var

  Child: TChildClass;

begin

  Child:= TChildClass.Create;

  Child.MessageBox();

  Child.Free;

end;

 

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/61930.html