关于面向对象的语法规则问题,不解啊? ( 积分: 100 )

  • 主题发起人 主题发起人 魏启明
  • 开始时间 开始时间

魏启明

Unregistered / Unconfirmed
GUEST, unregistred user!
这样的一个类结构:
type
TParamSubForm = class(TForm)
private
function Check: Boolean; virtual; abstract;
public
constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce; virtual;
procedure Load; virtual; abstract;
procedure Save; virtual; abstract;
end;

var
ParamSubForm: TParamSubForm;

implementation

{$R *.dfm}

constructor TParamSubForm.Create(AOwner: TComponent; AParent: TWinControl);
begin
inherited Create(AOwner);
Parent := AParent;
Align := alClient;
BorderStyle := bsNone;
end;

end.
…………
两个不懂的地方:
1、Create的再构造,为什么要加reintroduce关键字?
当这个类的体系从TPersistent到TComponent继承时,同样的改变了构造器的参数。但并没有使用reintroduce,而为什么此处需要(不加也只是Hint)。

2、三个纯虚函数
function Check: Boolean; virtual; abstract;
procedure Load; virtual; abstract;
procedure Save; virtual; abstract;
为什么只有Check被提示未被使用,他们只是对应子类时的可见度不同罢了
 
这样的一个类结构:
type
TParamSubForm = class(TForm)
private
function Check: Boolean; virtual; abstract;
public
constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce; virtual;
procedure Load; virtual; abstract;
procedure Save; virtual; abstract;
end;

var
ParamSubForm: TParamSubForm;

implementation

{$R *.dfm}

constructor TParamSubForm.Create(AOwner: TComponent; AParent: TWinControl);
begin
inherited Create(AOwner);
Parent := AParent;
Align := alClient;
BorderStyle := bsNone;
end;

end.
…………
两个不懂的地方:
1、Create的再构造,为什么要加reintroduce关键字?
当这个类的体系从TPersistent到TComponent继承时,同样的改变了构造器的参数。但并没有使用reintroduce,而为什么此处需要(不加也只是Hint)。

2、三个纯虚函数
function Check: Boolean; virtual; abstract;
procedure Load; virtual; abstract;
procedure Save; virtual; abstract;
为什么只有Check被提示未被使用,他们只是对应子类时的可见度不同罢了
 
从TPersistent到TComponent继承时,同样的改变了构造器的参数?怎么解释
 
//TObject
constructor Create;

//TComponent
constructor Create(AOwner: TComponent); virtual;

//TParamSubForm
constructor Create(AOwner: TComponent; AParent: TWinControl); reintroduce; virtual;
 
function Check: Boolean; virtual; abstract;
被定义成私有的,子类无法重载,因此出现提示。

reintroduce关键字很少用,因此不太清楚,估计是在重载某个祖先类的虚方法的时候,如果参数列表同祖先的虚方法的参数列表不一致,则需要reintroduce关键字,如果不是虚方法,那么子类只是简单地覆盖了祖先的同名方法。
像你说的,TPersistent类没有对Create方法进行重新定义,而TComponent则将Create定义为虚方法,好像也符合我上面的说法噢[:D]
 
Check的原因确实如此。
我将其申明转到protected部分就好了。

reintroduce的原因不是你所说的。
从TObject到TForm的继承结构中,Create的改变仅此一次

可能是Tobject的特殊性吧。
【源码】IniFiles中:
TCustomIniFile = class(TObject)
private
FFileName: string;
public
constructor Create(const FileName: string);
…………
具体为什么我还不清楚。但Delphi源码很少看到reintroduce,我不知是不需要还是被活略了
 
再引入指示字reintroduce用于防止编译器关于隐藏先前的虚拟方法给出警告。例如,procedure DoSomething; reintroduce; //祖先类中已经有一个DoSomething方法想要用新的方法隐藏继承得到的虚拟方法时,可以使用reintroduce。
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=17418
KeyLife富翁笔记
作者?: pengfeiyan
标题?: oop1
 
ak_2005的答案是《开发人员指南》的内容,我已经看过了。
app2001所指的笔记我也看过。结尾讲到构造器部分时,也可以看到我的疑惑的情况。

但是都无法解释

为什么这些地方没有加reintroduce
 
function Check: Boolean; virtual; abstract;
被定义成私有的,子类无法重载,因此出现提示。

reintroduce这个声明可有可无,当子类和父类有同名函数,但参数类型不同会出现错误提示
但不影响执行,使用reintroduce声明会屏蔽hint提示
 
我知道是可以不写的,但是Delphi制定的标准,自己会不执行???
 
reintroduce关键字在Delphi的联机帮助上说,是子类在以不同的参数列表重载祖先类的虚方法的时候才使用这个关键字。
应该注意到TObject的Create方法并没有被声明成一个虚方法,因此,子类在定义自己的Create方法的时候,没有必要使用reintroduce关键字,但是,如果子类是继承自一个将Create方法声明成虚方法的祖先类的时候,如果参数列表不一样,那就要使用这个关键字了。
例如TComponent类将Create方法声明成了虚方法,因此,如果TComponent的子类要改写Create的参数列表,就需要使用这个关键字。
 
reintroduce 去除编译期的警告。
 
放飞,谢谢你。
两个答案都是你提供的。

看来我是受《开发人员指南》的误导,经典也有错误啊。
在D6开发人员指南80页的例子。
我注意到前面的回复中一再提到虚方法,而编译提示中也是虚方法。
但是都因为这个错误的前期影响而被活略了。
 
其实,在第一个回复中,已经解答了,只是当时我还没有被点透……

其他人跟的也辛苦。
 

Similar threads

后退
顶部