从派生类调用基础构造函数时,不确定参数

时间:2014-04-11 16:28:01

标签: c# class inheritance constructor xna

我在游戏中实现继承权时遇到了一些麻烦。我认为最好引入继承,因为它会使我的代码更整洁,并以合理的方式组织。

我面临的问题是在从派生类的基类调用构造函数时使用参数。

我使用Paddle类作为基类,使用Player类作为继承Paddle的类。

代码如下所示:

在Paddle课程中......

//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)

在玩家类......

//properties
PlayerIndex pID;


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

在你提到它无法工作的原因之前是因为在Player类中调用的基础构造函数没有任何参数,而基类/ Paddle类中的构造函数确实如此,我理解这一点。我面临的问题是设置播放器的纹理,位置等,但是纹理,位置等都在基类中,因为它们是Player和Enemy类的常见属性(另一个继承自Paddle的类,但它类似玩家,因此现在只提到它)。我也不知道在Player类中调用基础构造函数时要将什么作为参数。

感谢您提前阅读并提供帮助: - )

我改变的代码如下:

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

2 个答案:

答案 0 :(得分:1)

要以这种方式使用构造函数,您必须为派生构造函数提供基本构造函数所需的所有信息,以便它可以像这样调用它:

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

然后传递给基地:

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

显然这会使Player构造函数变得更大。为了避免这个问题,你可以在基类上声明一个Init()函数(不可覆盖),该函数接受构造函数所做的所有参数,并在实例化后让拥有类调用它。无论哪种方式,你必须最终给班级所有的信息。

如果我能澄清任何内容或进一步帮助,请告诉我。

<强>更新

  1. 是的,:base(...)语法实际上与写入相同(如果它是有效的C#)myBaseClassPointer = new base(...);(在这种情况下base是Paddle)。同样,这不是有效的C#。实际上,您必须使用:base在使用非默认构造函数时实例化基类。它设置属性的方式与直接实例化它的方式相同,只要它们没有标记为私有,它们就可以从派生类中获得(子是有点用词不当,因为该术语通常指的是组合)。

  2. 我建议不要使用Init()函数,因为使用类不能保证调用它。话虽如此,它可以很好地工作:

    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 }
       }
    }
    
  3. 唯一的好处是您不必将Init()所需的所有数据传递给Player构造函数,因此不需要在Player类本身中存在这些字段的知识。它是有效的,只要额外的if检查没问题,你记得在实例化类中调用Init

答案 1 :(得分:0)

由于paddle对象具有PlayerEnemy共享的属性,因此组合是比继承更好的选择。 (通过继承,你不能破坏基础对象,因为该对象为每个对象构造独立)实现涉及构建(共享)Paddle,然后将其传递给Player和{{1}的c-tor }}

我不确定为什么Enemy属性如位置和速度被共享。 Paddle似乎是唯一应该共享的属性。如果这是像Pong之类的游戏,则每个玩家都有自己的位置和速度,但两者都是在同一个GUI组件上绘制的。如果是这种情况,Player和Enemy都是paddles并且inheritnace很好,但ViewPort则是共享的。实施涉及构建ViewPort并将其与ViewPort(或Player)的位置,速度等一起传递给Enemy(或{{1}然后将c-tor传递给基础Player c-tor