一个delphi接口继承问题 ( 积分: 100 )

  • 主题发起人 主题发起人 charl
  • 开始时间 开始时间
C

charl

Unregistered / Unconfirmed
GUEST, unregistred user!
Eric Harmon的《Delphi COM深入编程》中有这么一个例子:

type
IFormattedNumber = interface
['{……}']
function FormattedString:string;
function GetName:string;
end;

TFormattedInteger = class(TInterfacedObject,IFormattedNumber)
private
FValue: Integer;
public
constructor Create(AValue: integer);
destructor Destroy;override;
function FormattedString:string;
function GetName:string;
end;

TFormattedHexInteger = class(TFormattedInteger,IFormattedNumber)
private
FValue: Integer;
public
destructor Destroy;override;
function FormattedString:string;
function GetName:string;
end;

FormattedString和GetName已经是TFormattedInteger类的公有方法了,它的子类TFormattedHexInteger再声明这两个方法是否应该加上override关键字?
谢谢!
 
Eric Harmon的《Delphi COM深入编程》中有这么一个例子:

type
IFormattedNumber = interface
['{……}']
function FormattedString:string;
function GetName:string;
end;

TFormattedInteger = class(TInterfacedObject,IFormattedNumber)
private
FValue: Integer;
public
constructor Create(AValue: integer);
destructor Destroy;override;
function FormattedString:string;
function GetName:string;
end;

TFormattedHexInteger = class(TFormattedInteger,IFormattedNumber)
private
FValue: Integer;
public
destructor Destroy;override;
function FormattedString:string;
function GetName:string;
end;

FormattedString和GetName已经是TFormattedInteger类的公有方法了,它的子类TFormattedHexInteger再声明这两个方法是否应该加上override关键字?
谢谢!
 
FormattedString和GetName在TFormattedInteger类中不是虚方法,
所以字类是不能override的,编译都通不过。现在的效果是字类的同名方法
把父类的方法替代并隐藏了。
 
这个例子还有一些不明白的地方:
上面类中一些方法的具体定义如下:
constructor TFormattedInteger.Create(AValue: integer)

begin
inherited Create

FValue := AValue

end


function TFormattedInteger.FormattedString: string

begin
result:= 'The Integer is '+IntToStr(FValue)

end;

function TFormattedHexInteger.FormattedString: string

begin
result:= 'The Hex Integer is $'+IntToHex(FValue,4)

end

现在在主程序中执行如下过程:
procedure TForm1.btnAsInterfaceClick(Sender: TObject)

var
myIntf: IFormattedNumber

begin
myIntf:= TFormattedHexInteger.Create(1537)

memo1.Lines.Add(myIntf.FormattedString)

……
end

输出为:
The Hex Integer is $0000

请问怎样才能输出正确的16进制数?上面的代码错在哪里?
谢谢!
 
你TFormattedHexInteger类私有字段FValue把父类的同名字段给覆盖了,这样
此字段在父类的构造函数赋值对子类没有意义,所以要在TFormattedHexInteger中
去掉这个定义。
 
感谢xeen兄指点!但是去掉TFormattedHexInteger中的FValue后,FValue作为
TFormattedInteger的私有成员,怎么可以出现在TFormattedHexInteger.FormattedString
中呢?
 
一般可以把FValue 定义成protected,这样在子类中也能访问,
或者也可以定义访问器 GetFValue,SetFValue...,把访问器定义成public或proteced
 
抱歉,我的意思是说:为什么将FValue声明成私有却能够通过编译而没有报“访问越界”的错误呢?
 
Delphi 语法规定,在在同一个Unit内,可以自由地访问类的所有成员,
包括private!
你这两个类放在不同单元就没这种事情了。
 
还有一个问题:
如果将TFormattedHexInteger的声明改为:
TFormattedHexInteger = class(TFormattedInteger)
再执行
myIntf:= TFormattedHexInteger.Create(1537)

memo1.Lines.Add(myIntf.FormattedString)

myIntf.FormattedString执行的是TFormattedInteger的FormattedString而不是
TFormattedHexInteger的FormattedString,造成这种变化的原因是什么?
 
TFormattedHexInteger = class(TFormattedInteger)
这说明IFormattedNumber不由此类实现,而由起父类实现.
我在前面说过,由于FormattedString在父类中为非虚函数,所以子类的FormattedString
与父类的FormattedString没有任何关系,所以调用接口方法还是会调用父类的方法。
要实现你要的效果,必须在父类方法后加virtual,子类方法后加override.
 
十分感谢xeen兄的耐心解答!
结帖
 

Similar threads

I
回复
0
查看
682
import
I
I
回复
0
查看
604
import
I
I
回复
0
查看
728
import
I
后退
顶部