delphidelphi-6

Getting value of a subclass of a subclass on Delphi


Thanks to Andreas Rejbrand for helping me improve this question.

I'm creating a program that has the featuring classes and subclasses:

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;

On the var section, I created one instance of the SubClasses BallLow and BallHigh for each ball group and was doing separate feature for each team and ball type:

Ball1 : TBilliardBallLow;
Ball2 : TBilliardBallLow;
Ball3 : TBilliardBallLow;
Ball4 : TBilliardBallLow;
Ball5 : TBilliardBallLow;
Ball6 : TBilliardBallLow;
Ball7 : TBilliardBallLow;
Ball9 : TBilliardBallHigh;
Ball10: TBilliardBallHigh;
Ball11: TBilliardBallHigh;
Ball12: TBilliardBallHigh;
Ball13: TBilliardBallHigh;
Ball14: TBilliardBallHigh;
Ball15: TBilliardBallHigh;

I was working on a method, that I concluded that It needs to receive one parameter for a ball, and can be the High numbers or Low numbers. If i create a function that receives a TBilliardBall, and try to send one of the instances i created, will it work?
I was thinking of something like that:
procedure Button1OnClick(Sender: TObject)
begin
TBall.Hit(Ball1);
end;

procedure TBall.Hit(BallHit: TBilliardBall);
begin
Ballhit.Validpot;
end;

I need to have the method validPot in my program, is there any way to do it?


Solution

  • Yes,

    procedure TBall.Hit(BallHit: TBilliardBall);
    begin
      BallHit.ValidPot;
    end;
    

    is a perfectly valid method, since ValidPot is a public method of TBilliardBall. But you must not pass an instance of TBilliardBall to this method, because that is an abstract class without an implementation of ValidPot. Instead, you must pass a TBilliardBallLow or a TBilliardBallHigh object. By declaring the BallHit parameter as a general TBilliardBall, you are free to pass a billiard ball of either of those types.

    Also, in your example at least, this is a method of TBall. Hence, in the interface section, you must declare this method properly:

    TBall = class
    private
    public    
      procedure Hit(BallHit: TBilliardBall);
    end;
    

    Now, there is a slight problem. When you declare the TBall class in the interface section, you haven't yet declared TBilliardBall, so it remains an undeclared type. And obviously you cannot simply reverse the order and declare TBilliardBall before TBall.

    The solution is to use a forward declaration:

    TBilliardBall = class; // <-- a forward declaration
    
    TBall = class
    private
    public    
      procedure Hit(BallHit: TBilliardBall);
    end;