子类和可变继承

本文关键字:继承 子类 | 更新日期: 2023-09-27 18:31:46

我开始和我的朋友在C#的XNA游戏库中做一些小游戏,我做了一个Player类,它太大而无法发布,但有一个受保护的变量:

protected int moveSpeed = 3; (which affects how fast Player can move)

我有一个班级孩子,Fighter,因为游戏将基于不同的战斗类型,我希望战士继承玩家的属性(包括变量)。例如:moveSpeed,但是每当我尝试为 Fighters 分配 moveSpeed 的特定值时,它都不会让我公开声明 moveSpeed = 2; ,例如说:moveSpeed 是一个FIELD,但用作TYPEC#没有直接变量访问,还是仅适用于函数/方法。

PS:我从来没有在C#中搞过继承,只有java。任何帮助,非常感谢,谢谢。

子类和可变继承

你不想

重新声明变量,你只想改变它的值。 您最好在构造函数中执行此操作:

public class SomeTypeOfPlayer : Player
{
  //protected int moveSpeed = 2; DON'T DO THIS! It would be 
  //re-defining it, not setting the existing field.
  public SomeTypeOfPlayer()
  {
    moveSpeed = 2;  //Do this
  }
}

查看描述,您的代码如下所示:

  public class Player
  {
       public double MoveSpeed {get;set}
  }
  public class Fighter : Player 
  {
  }

像基类的自动属性一样声明MoveSpeed(避免声明像public这样的字段并直接访问,但为此使用属性)

每当我尝试为 Fighter 分配 moveSpeed 的特定值时,它都不会让我公开声明 moveSpeed = 2;,例如:moveSpeed 是一个字段,但用作类型

通常,当您在类中编写赋值语句(如moveSpeed = 2;)时,会发生这种情况,而它应该在方法或构造函数中。

错误消息有点令人困惑,但它是有道理的:类中的语句通常以类型(int bla = 123;)开头,而在这种情况下,第一个单词是变量的名称(moveSpeed)。

只需moveSpeed = 2;移动到构造函数(或方法或属性),即可解决问题。

您将 MoveSpeed 声明为protected字段。因此,您可以在 Player 的派生类中访问它。但是你不能在那之外访问它。如果您有Property也可以在派生类外部访问它。创建自动属性时,将在后台创建 Getter 和 Setter 方法,以设置和检索备份字段的值(由 CLR 创建)。

假设你的类结构是这样的

public class Player
{
 public int MoveSpeed { set;get;}    
}
public class Fighter : Player
{
 public int FigherTypeId { set;get;}
}

您应该能够像这样设置播放器移动速度

Fighter objFighter=new Fighter();
objFighter.MoveSpeed=35;

如果要将字段保留为 Protected ,则可以执行此操作并在子类构造器中设置属性值

public class Player
{
 protected int MoveSpeed =3;
}
public class Fighter : Player
{
    public int FigherTypeId { set; get; }
    public Fighter(int _moveSpeed)
    {
        MoveSpeed = _moveSpeed;
    }
}

并像这样创建子类对象

Fighter objFighter = new Fighter(44); 

http://blogs.msdn.com/b/ericlippert/archive/2005/11/09/491031.aspx

鉴于您的描述,在我看来,您需要 moveSpeed 成为常量(即无法在运行时更改)? 我这样说是因为听起来你想要一个速度为 2 的基本玩家,但想要创建一个派生的战斗机类,它能够以更快的速度移动,但这些速度对于每种类型的玩家都是固定的。

你不能有一个虚拟

的常量,但你可以有一个只有一个getter的虚拟属性:

public virtual class Player
{
    protected virtual int MoveSpeed { get { return 2; } }
}
public class Fighter : Player
{
    protected override int MoveSpeed { get { return 3; } }
}