Home > Enterprise >  C# Abstract Class having Abstract Variables
C# Abstract Class having Abstract Variables

Time:08-14

We have an abstract class called Game.

public abstract class Game
{
   protected Player player;

   public virtual void InitPlayer()
   {
      // steps
      player = new Player(xxxxxxx);
   }

   // Other methods manipulating data from player.
}

and there are two child classes of Game , let's say GameA and GameB.

public class GameA : Game
{     
    public override void InitPlayer()
    {
        base.InitPlayer();
    }
}

However, Player Variable in Game Class is also Abstract, having PlayerGameA and PlayerGameB.

public abstract class Player
{
}

public class PlayerGameA : Player
{
}

Note that Player and PlayerGameA Constructors have same arguments.

Now I have a problem about creating an instance of Abstract Class in InitPlayer Method. The result what I want is unifying result when creating an instance of GameA and calling gameA.InitPlayer() will create playerGameA ,and still other methods from GameClass needs to be able to manipulate data from that player variable.

CodePudding user response:

You can take a number of approaches. A straightforward one is to make your concrete sublclass of Game responsible for providing a concrete implementation of Player, e.g.:

public abstract class Game
{
    protected Player player;

    protected void InitPlayer(Player concretePlayer)
    {
        // steps
        player = concretePlayer;
    }
}

public class GameA : Game
{
    public void InitPlayer()
    {
        base.InitPlayer(new PlayerGameA());
    }
}

CodePudding user response:

A better approach is to make Game accept a generic parameter TPlayer.

But you should place any non-generic functionality in a GameBase non-generic class

public abstract class GameBase
{
    // non generic functionality here
}

public abstract class Game<TPlayer> : GameBase where TPlayer : Player
{
    protected TPlayer player;

    protected void InitPlayer(TPlayer concretePlayer)
    {
        // steps
        player = concretePlayer;
    }
}

public class GameA : Game<PlayerGameA>
{
    public void InitPlayer()
    {
        base.InitPlayer(new PlayerGameA());
    }
}
  • Related