6a6179
6a6179

Reputation: 280

Unsure about parameters when calling base constructor from derived class

I am having some troubles implementing inheritence into my game. I thought that it would be best to introduce inheritence, as it would make my code neater and organised in a logical way.

The problem i am facing atm is with the parameters when calling the constructor from the base class in the derived class.

I am using the Paddle class as the base class and the Player class as the class inheriting Paddle.

The code is shown below:

In the Paddle class....

//properties

  protected Texture2D pTexture;
  protected Vector2 pPosition;
  protected Vector2 pVelocity;


//constructor for Paddle class (only first line here, as the rest is irrelevant)

public Paddle(Texture2D newTexture, Vector2 newPosition, Viewport theViewport, Color newColour)

In the Player class....

//properties
PlayerIndex pID;


//constructor for Player class (only first line here, as the rest is irrelevant)
public Player(PlayerIndex newID) : base()

Before you mention the reason why its not working is because the base constructor im calling in the Player class doesn't have any parameters, whereas the constructor in the base class/Paddle class does, i understand that. The problem i am facing is setting the texture, position, etc of the player but the texture, position, etc are in the base class, as they are common properties for the Player and Enemy class (another class that inherits from Paddle but it's similar to Player, hence only mentioning it now). I also don't know what to put as the parameters when calling the base constructor in the Player class.

Thanks for reading and for the help in advance :-)

ADDED CODE I'VE CHANGED BELOW:

public Player(PlayerIndex newID, Texture2D newTexture, Vector2 newPosition, Viewport theViewport, Color newColour)
        : base(newTexture, newPosition, theViewport, newColour)

Upvotes: 0

Views: 391

Answers (2)

BradleyDotNET
BradleyDotNET

Reputation: 61369

To use the constructor in this way, you have to give the derived constructor ALL of the information needed for the base constructor, so that it can call it like so:

public Player(PlayerIndex newID, Texture2D newTexture, Vector2 newPosition, Viewport theViewport, Color newColour)

You then pass to the base:

public Player(PlayerIndex newID, Texture2D newTexture, Vector2 newPosition, Viewport theViewport, Color newColour) : base(newTexture, newPosition, theViewport, newColour);

Obviously this makes the Player constructor quite a bit larger. To avoid this problem, you could declare an Init() function on the base class (non-overridable) that takes all the parameters the constructor does, and have the owning class call it after instantiation. Either way, you have to give the class all the information eventually.

Let me know if I can clarify anything or help further!.

Update

  1. Yes, the :base(...) syntax is effectively the same thing as writing (if it were valid C#) myBaseClassPointer = new base(...); (where base is Paddle in this case). Again, this is not valid C#. You actually have to use :base to instantiate the base class when using a non-default constructor. It sets properties the same way as if you had instantiated it directly, and as long as they are not marked private, they will be available from the derived class (child is a bit of misnomer, since that term generally refers to composition).

  2. I'm not recommending the use of an Init() function, as the using class isn't guaranteed to call it. That being said, it could work pretty well like so:

    class Player
    {
       private bool initialized = false;
       public Player()
       {}
    
       public void Init(Texture2D newTexture, Vector2 newPosition, Viewport theViewport, Color newColour)
       {
          //All the stuff your constructor used to do
          initialized = true;
       }
    
       public void SomeFunctionUsingVariables()
       {
       if (initialized)
       { //Do whatever }
       }
    }
    

The only advantage is you don't have to pass all the data that Init() needs to the Player constructor, so knowledge of these fields doesn't need to exist in the Player class itself. It works, as long as the extra if checks are ok and you remember to call Init in the instantiating class.

Upvotes: 1

Jonathan
Jonathan

Reputation: 1377

Since the paddle object has properties that are shared by both Player and Enemy, composition is a better choice than inheritance. (Via inheritance you cannot shre a base object since that object gets independly constructed for each object) Implementation involves constructing a (shared) Paddle that is then passed to the c-tor for Player and Enemy.

I am not sure why Paddle properties such as position and velocity are shared. ViewPort seems to be the only property that should be shared. If this a game like Pong or the like, each player has its own location and velocity but both are drawn on the same GUI component. If that is the case, both Player and Enemy are paddles and inheritnace is fine, but the ViewPort then is shared. Implementation involves consructing a ViewPort and passing it, along with the Player's (or Enemy's) location, velocity, etc to the Player (or Enemy) c-tor which will then pass them onto the base Paddle c-tor

Upvotes: 0

Related Questions