请教"方法的重载与虚方法"的问题. (30分)

  • 主题发起人 主题发起人 罗子
  • 开始时间 开始时间

罗子

Unregistered / Unconfirmed
GUEST, unregistred user!
1. 如何理解"虚方法" 这个词?
我在一本中看到一个很不明确的概念,说虚方法是没有过程(函数体)的方法.
我知道这样的说法是错误的.因为我验证过了,在一个有过程体的方法的称明之后加上 virtual 并没有错.如:以下代码可以正确通过编译.
TMammal=class
public
procedure GiveBirth ;virtual;
end;
implementation

procedure Tmammal.GiveBirth;
begin
showmessage('出生方式');
end;

2. "声明了虚方法,就意味着某个时候该类被子类化,而方法在子类中被重载.只有在
某个祖先中声明的虚方法才能进行重载"这句话好像也是错误的.
TMammal=class
public
procedure GiveBirth ;
end;

TEggLayingMammal=class(Tmammal)
private
procedure LayEggs;
public
procedure GiveBirth;
end;
implementation
procedure Tmammal.GiveBirth;
begin
showmessage('出生方式');
end;

procedure TeggLayingMammal.LayEggs;
begin
showmessage('Laying Eggs');
end;

procedure TeggLayingMammal.GiveBirth;
begin
layeggs;
end;
//以上Tmammal的GiveBirth 并没有 virtual 指令.借一切正常运行.加上了Virtual 也一样运行.可能是我对重载的概念不清楚吧(从VB到Delphi6的)
请对以上的两个问题说说你的看法.
 
virtual 就表示继承的类必须重载它,如果你不加,在子类用一个同样的函数并不会出错,只是调用的时候不关父类的事了
 
1。那是纯虚方法,
procedure GiveBirth ;virtual;abstract;
试一下
2。重载和继承是两回事
TEggLayingMammal=class(Tmammal)
private
procedure LayEggs;override;
public
procedure GiveBirth;
end;

procedure TeggLayingMammal.GiveBirth;
begin
inherited;
layeggs;
end;
这样试一下
 
谢谢 沉香屑:!
我试试之后回来!
 
我并不是这方面高手,谬见如下:
1、virtual方法可以在子类中实现,但不是不可以在本类中实现
2、你把virtual;和virtual;abstract;弄混了
 
去掉virtual将掩盖子类的方法,即子类的方法与父类没有关系,见上例
 
1、举例如下
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type
TFigure = class
private
procedure Draww;virtual;
end;
TRectangle = class(TFigure)
procedure Draww; //override;
end;
TEllipse = class(TRectangle)
procedure Draww; //override;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TFigure.Draww;
begin
showmessage('calls TFigure.Draw');
end;

procedure TRectangle.Draww;
begin
showmessage('calls TRectangle.Draw');
end;

procedure TEllipse.Draww;
begin
showmessage('calls TEllipse.Draw');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Figure: TRectangle;
begin
Figure := TRectangle.Create;
Figure.Draww; // calls TRectangle.Draw
Figure.Destroy;
Figure := TEllipse.Create;
Figure.Draww; // 预calls TEllipse.Draw,但不可能
Figure.Destroy;
end;




end.
 
to yy2001:
因为初次结束这种问题,对于我来说要理解这个问题还是有一定的难度的.
现在你能给我说说为什么 Ellipse 的 Draw 方法不能被调用吗?
 
你运行一下程序就会发现,两次结果都一样,没有分别显示'calls TRectangle.Draw'
和'calls TEllipse.Draw',把两个override前的//去掉就可以了,简单的说,同一下
原理一样,你定义一个与Delphi相同的函数名将不被调用,因为缺少了virtual,子类
中的同名函数与父类中没有关系,不是重载,只是同名而已,与换一个不同名函数相似
 
to yy2001:
意思就是说:如果父类的方法如果没有 Virtual .则子类是不可能继承父类的方法了.
而子类要能够继承父类方法的功能,则要求父类方法是虚方法(virtual).并且在子类中定义与
父类相同方法名之后就可以了!.
是这样的意思码?
 
to yy2001:
对于你给我的例子.我去掉 Tfigure 的方法 Draww 之后的 virtual; 可是子类还是能够正常继
承Tfigure 的 Draww方法.(有没有 virtual 都一样的结果,都能继承)
"去掉virtual将掩盖子类的方法,即子类的方法与父类没有关系,见上例" 这句话的意思是
将父类的方法掩盖子类的同名方法?
 
你的上述两段话是对的,但可以看出
你的错误概念太多了,建议看一下相关书籍中有关面向对象编程的概念
1、只要是子类,就可以继承父类的方法,与有没有virtual没有关系,继承是面向对象的
基本特征之一;
2、virtual与override影响的是“重载”,不能在父类中定义的是抽象方法(abstract)
抽象方法必须是虚拟的或动态的;
去掉下述程序中的{},程序将不能被执行,因抽象方法不能在父类中定义

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

type
TFigure = class
private
procedure Draww;virtual;abstract;
end;
TRectangle = class(TFigure)
procedure Draww; override;
end;
TEllipse = class(TRectangle)
procedure Draww; override;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}
{
procedure TFigure.Draww;
begin
showmessage('calls TFigure.Draw');
end;
}
procedure TRectangle.Draww;
begin
showmessage('calls TRectangle.Draw');
end;

procedure TEllipse.Draww;
begin
showmessage('calls TEllipse.Draw');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Figure: TRectangle;
begin
Figure := TRectangle.Create;
Figure.Draww; // calls TRectangle.Draw
Figure.Destroy;
Figure := TEllipse.Create;
Figure.Draww; // calls TEllipse.Draw
Figure.Destroy;
end;




end.



 
不好意思。我也太水了,不过有你的帮助我相信我以后会更好一些的。
你的QQ能造诉我吗?
我的是:88495208
 
本人接受答案了。
 

Similar threads

后退
顶部