Delphi中的抽象

Delphi中的抽象,delphi,class,Delphi,Class,如果我有子类,子类将继承父类的所有方法,但是如何在父类中使用子类的函数呢?这就是抽象吗?我如何完成它 我的代码: type cParent = class(TObject) private function ParentFunction:byte; function ChildFunction:byte;virtual;abstract; end; type cChild = class(cParent) private function ChildFunction:byte;over

如果我有子类,子类将继承父类的所有方法,但是如何在父类中使用子类的函数呢?这就是抽象吗?我如何完成它

我的代码:

type
cParent = class(TObject)
private
  function ParentFunction:byte;
  function ChildFunction:byte;virtual;abstract;
end;

type
cChild = class(cParent)
private function ChildFunction:byte;override;
end;

function cChild.ChildFunction:byte;
begin
  Exit(20);
end;

function cParent.ParentFunction:byte;
begin
  Exit(10);
end;

var
c:cParent;

begin
  c:= cParent.Create;
  WriteLn(c.ChildFunction);
  Readln;
end.

它编译文件,但我得到抽象异常。

使用子类创建实例:

c:= cChild.Create;

使用子类创建实例:

c:= cChild.Create;
您可以在这里创建cParent类的实例。此类仅包含可由其他类重写的抽象ChildFunction。该函数未在cParent中实现,因此会出现一个抽象错误

如果改为使用cChild类,则代码有效,其中实现了ChildFunction:

c:= cChild.Create;
WriteLn(c.ChildFunction);
为了澄清问题,假设一个名为
GeometricObject
的父类使用虚拟抽象方法
CalculateVolume
。现在,您可以创建子类,如
SphereObject
BoxObject
,通过使用球体/长方体的公式来实现
CalculateVolume
。但是创建
GeometricObject
的实例并调用
CalculateVolume
是没有意义的

您可以在这里创建cParent类的实例。此类仅包含可由其他类重写的抽象ChildFunction。该函数未在cParent中实现,因此会出现一个抽象错误

如果改为使用cChild类,则代码有效,其中实现了ChildFunction:

c:= cChild.Create;
WriteLn(c.ChildFunction);

为了澄清问题,假设一个名为
GeometricObject
的父类使用虚拟抽象方法
CalculateVolume
。现在,您可以创建子类,如
SphereObject
BoxObject
,通过使用球体/长方体的公式来实现
CalculateVolume
。但是在创建cParent类的实例时,创建一个
GeometricObject
实例并调用
CalculateVolume

是没有意义的。此类没有childFunction的实现。c必须是cChild类的实例。 正确代码: c:=cChild.Create;
WriteLn(c.ChildFunction)

创建cParent类的实例。此类没有childFunction的实现。c必须是cChild类的实例。 正确代码: c:=cChild.Create;
WriteLn(c.ChildFunction)

我觉得你把继承关系和占有关系搞混了。如果将类“cChild”定义为继承自类“cParent”,那么类“cChild”就是一个“cParent”,这并不意味着类“Parent”可以访问任何子类。在类“cParent”中调用抽象函数“ChildFunction”的唯一方法是从另一个函数,例如“ParentFunction”,但仅当对象本身不是“cParent”时:


在这里,由于c是一个cChild,ParentFunction正确地调用了在cChild中定义的ChildFunction。

在我看来,您混淆了继承关系和占有关系。如果将类“cChild”定义为继承自类“cParent”,那么类“cChild”就是一个“cParent”,这并不意味着类“Parent”可以访问任何子类。在类“cParent”中调用抽象函数“ChildFunction”的唯一方法是从另一个函数,例如“ParentFunction”,但仅当对象本身不是“cParent”时:


这里,由于c是一个cChild,ParentFunction正确地调用了在cChild中定义的ChildFunction。

响应schnaader,关于CS 101:

“virtual”表示该方法可以被子类重写。
不仅如此,非虚函数也可能被子类覆盖。区别非常重要:当父类调用虚拟函数时,将执行子函数。这允许子类实现将由父类调用的函数,而父类对这些函数一无所知。这就是多态性的本质。

对于schnaader,关于CS 101:

“virtual”表示该方法可以被子类重写。
不仅如此,非虚函数也可能被子类覆盖。区别非常重要:当父类调用虚拟函数时,将执行子函数。这允许子类实现将由父类调用的函数,而父类对这些函数一无所知。这就是多态性的本质。

好的,但是“virtual”、“abstract”和“override”关键字的用法是什么?“virtual”意味着该方法可以被子类重写。“抽象”表示该方法不是由父类实现的,而是可以在子类中实现的。“override”覆盖父类中的虚拟方法。所有抽象方法都必须是虚拟的,但是方法可以是虚拟的而不是抽象的。抽象方法是C++所指的“纯虚拟”方法。它们必须在子类中实现。好的,但是“virtual”、“abstract”和“override”关键字的用法是什么?“virtual”意味着该方法可以被子类重写。“抽象”表示该方法不是由父类实现的,而是可以在子类中实现的。“override”覆盖父类中的虚拟方法。所有抽象方法都必须是虚拟的,但是方法可以是虚拟的而不是抽象的。抽象方法是C++所指的“纯虚拟”方法。它们必须在子类中实现。当你说它编译得很好时,你真的是说编译器没有警告你正在实例化一个抽象类吗?您需要更加努力地消除编译器提示和警告,而不仅仅是错误。只是一些关于传统风格的注释。在Delphi中,通常用T而不是c作为类(和其他类型)名称的前缀。函数的返回值通常通过将隐式结果变量设置为值r来设置