在Delphi上获取子类的子类的值

在Delphi上获取子类的子类的值,delphi,delphi-6,Delphi,Delphi 6,谢谢你帮助我改进这个问题。 我正在创建一个具有特色类和子类的程序: TBall= class private public procedure Hit; end; TBilliardBall = class(TBall) private number:integer; public procedure ValidPot; virtual; abstract; end; TBilliardBallLow= class(TBilliardBall) private p

谢谢你帮助我改进这个问题。 我正在创建一个具有特色类和子类的程序:

TBall= class
private
public    
  procedure Hit;
end;

TBilliardBall = class(TBall)
private
  number:integer;
public    
  procedure ValidPot; virtual; abstract;
end;

TBilliardBallLow= class(TBilliardBall)
private
public
  procedure ValidPot();override;
end;

TBilliardBallHigh= class(TBilliardBall )
private
public
  procedure ValidPot();override;
end;
在var部分,我为每个球组创建了一个子类BallLow和BallHigh的实例,并为每个队和球类型创建了单独的功能:

我正在研究一种方法,我得出结论,一个球需要接收一个参数,可以是高数值,也可以是低数值。如果我创建一个接收TBilliardBall的函数,并尝试发送我创建的一个实例,它会工作吗? 我在想这样的事情: 我需要在我的程序中使用validPot方法,有什么办法吗?

procedure TBall.Hit(BallHit: TBilliardBall);
begin
  BallHit.ValidPot;
end;
是一个非常有效的方法,因为ValidPot是TBilliardBall的公共方法。但您不能将TBilliardBall的实例传递给此方法,因为它是一个没有ValidPot实现的抽象类。相反,您必须传递TBilliardBallLow或TBilliardBallHigh对象。通过将BallHit参数声明为一般TBilliardBall,您可以自由地传递这两种类型的台球

另外,至少在您的示例中,这是一种TBall方法。因此,在接口部分中,必须正确声明此方法:

TBall = class
private
public    
  procedure Hit(BallHit: TBilliardBall);
end;
现在,有一个小问题。当您在接口部分声明TBall类时,您还没有声明TBilliardBall,因此它仍然是一个未声明的类型。显然,你不能简单地颠倒顺序,在TBall之前声明TBilliardBall

解决方案是使用:

是一个非常有效的方法,因为ValidPot是TBilliardBall的公共方法。但您不能将TBilliardBall的实例传递给此方法,因为它是一个没有ValidPot实现的抽象类。相反,您必须传递TBilliardBallLow或TBilliardBallHigh对象。通过将BallHit参数声明为一般TBilliardBall,您可以自由地传递这两种类型的台球

另外,至少在您的示例中,这是一种TBall方法。因此,在接口部分中,必须正确声明此方法:

TBall = class
private
public    
  procedure Hit(BallHit: TBilliardBall);
end;
现在,有一个小问题。当您在接口部分声明TBall类时,您还没有声明TBilliardBall,因此它仍然是一个未声明的类型。显然,你不能简单地颠倒顺序,在TBall之前声明TBilliardBall

解决方案是使用:

为什么首先要声明TBilliardBallLow和TBilliardBallHigh子类?如果您将LowBall或HighBall作为TBilliardBall类的属性,这不是更容易吗

既然你们已经在你们的TBilliardBall类中存储了球数,那个么你们就可以通过简单的数学比较轻松地计算出特定的球是低球还是高球。所以你们班的TBilliardBall班看起来像这样:

TBilliardBall = class(TBall)
private
  number:integer;
protected 
  function GetHigh: Boolean;
public    
  procedure ValidPot;
  property IsHigh: Boolean; read GetHigh;
end;

implementation

function TBilliardBall.GetHigh: Boolean;
begin
  if FNumber > 7 then result := True
  else Result := False;
end;
为什么首先要声明TBilliardBallLow和TBilliardBallHigh子类?如果您将LowBall或HighBall作为TBilliardBall类的属性,这不是更容易吗

既然你们已经在你们的TBilliardBall类中存储了球数,那个么你们就可以通过简单的数学比较轻松地计算出特定的球是低球还是高球。所以你们班的TBilliardBall班看起来像这样:

TBilliardBall = class(TBall)
private
  number:integer;
protected 
  function GetHigh: Boolean;
public    
  procedure ValidPot;
  property IsHigh: Boolean; read GetHigh;
end;

implementation

function TBilliardBall.GetHigh: Boolean;
begin
  if FNumber > 7 then result := True
  else Result := False;
end;

TBilliardBall不是TBall吗?另外,我为每个球创建了一个子类。你可能是说我为桌子上的每个球创建了一个球实例;每一个球不是一个亿巴罗,就是一个亿巴罗。从技术上讲,在var部分,您不创建对象。您只声明变量。在代码块中,您可以创建对象并将它们的指针分配给这些变量。@AndreasRejbrand谢谢您的提醒,将我的代码翻译成english@AndreasRejbrand是的,这就是我想说的,TBilliardBall不是TBall吗?而且,我为每个球创建了一个子类。你可能是说我为桌子上的每个球创建了一个球实例;每一个球不是一个亿巴罗,就是一个亿巴罗。从技术上讲,在var部分,您不创建对象。您只声明变量。在代码块中,您可以创建对象并将它们的指针分配给这些变量。@AndreasRejbrand谢谢您的提醒,将我的代码翻译成english@AndreasRejbrand是的,这就是我想说的我需要两种方法中的一种:台球球球低或台球球球高,这就是为什么我试图找到一个解决方案,因为其中两个看起来不必要。谢谢你向我解释,我需要两个方法中的一个:台球球球低或台球球球高,这就是为什么我试图找到一个解决方案,因为其中两个看起来不必要。谢谢你向meI解释,我正在做一个练习,我需要用那些特定的名称创建那些子类,这就是原因。我正在处理8球分隔
因为8号球有一些规则不适用于其他球,我需要验证,在另一个过程中,我正在做一个练习,我需要创建具有这些特定名称的子类,这就是原因。我将8个球与其他球分开处理,因此FNumber>7可能会导致一些问题,因为8个球有一些规则不适用于其他球,我需要在另一个过程中验证这一点
TBilliardBall = class(TBall)
private
  number:integer;
protected 
  function GetHigh: Boolean;
public    
  procedure ValidPot;
  property IsHigh: Boolean; read GetHigh;
end;

implementation

function TBilliardBall.GetHigh: Boolean;
begin
  if FNumber > 7 then result := True
  else Result := False;
end;