【问题标题】:Using Inheritance in C# to share functions在 C# 中使用继承来共享函数
【发布时间】:2012-03-26 18:22:59
【问题描述】:

所以我对继承和接口的想法很陌生,我不确定如何实现我想要做的事情。

我有一个角色类,它定义了角色的位置、旋转方向、纹理,然后我想用 Player 和 Enemy 类继承这个类,这样我就可以为 Players 和 Enemy 使用相同的运动和绘图类敌人,同时添加额外的功能来控制 AI。

所以我有静态播放器类继承的角色类,但我无法通过播放器类访问位置,它说需要对象引用。

那么我如何使用继承在玩家和ai之间共享函数,同时仍然能够通过子类访问角色类中的变量?

【问题讨论】:

  • 静态播放器类?不不不。您将使其难以测试和扩展。使您的播放器类成为普通类,您的object reference required 错误和测试/扩展应用程序的困难都将消失。
  • 如果Player类继承了Character,怎么可能是staticstatic 类只能从 object 继承。
  • @BACON,它没有抛出编译器错误,只是没有帮助

标签: c# .net inheritance interface


【解决方案1】:

如果您希望子类能够访问变量,则父“字符”类需要将其非公共成员声明为“受保护”,而不是“私有”。之后,您只需使用“base”关键字来引用父级,类似于使用“this”来引用类的当前实例的方式。

例如:

//note: abstract is not a pre-requisite for inheritance
abstract class Character
{
     protected float x;
     protected float y;
     protected float z;
     //etc etc
}

public class AIBasic : Character
{
    public void move()
    {
         //purely an example
         base.x++;
         base.y++;
         base.z++;
    }
}

【讨论】:

  • 感谢您告诉我有关基本关键字的信息,我会记住这一点的。
【解决方案2】:

将您的基类实现为抽象类,而不是静态类。静态方法在不引用实际对象的情况下将无法访问对象的属性或字段。

【讨论】:

  • 谢谢,这很有帮助,我认为我可以使用 Player 对象代替 Character 对象,因为它继承了它?
  • 我不确定您所说的“代替”是什么意思,但如果 Player 继承自 Character,则意味着任何 Player 实例也是 Character 实例。
  • 是的,这就是我的意思,谢谢,例如,我可以将 Player 对象添加到字符列表中。
【解决方案3】:

继承并不是解决这个问题的最佳方法。而是考虑使用 IoC(控制反转)并创建单独的绘图和移动类。然后将它们组合成单个字符实例。

Ninject 是我最喜欢的 IoC 工具之一,他们的教程相当完整。事实上,它演示了一个非常简单但常见的游戏角色类。

https://github.com/ninject/ninject/wiki/Injection-Patterns

【讨论】:

  • 我没有太多时间来完成这个项目,但是我已经将该页面添加到我的收藏夹中,以便在我有更多时间玩的时候去看看它。谢谢
【解决方案4】:

所以你要做的第一件事就是定义基类。如果你不想实例化它,你可以创建一个抽象类,然后允许重写属性和方法:

// Marking the properties as virtual allow you to override their behaviour 'by design'. Their normal
// behaviour will continue to work if you choose not to
public abstract class Character
{
     protected virtual Point Position { get;set; }
     protected virtual int Direction {get;set; }
     protected virtual Image Texture { get;set; }
     protected virtual bool Visible { get; set; }

     // Define methods you would like to partially implement or let the other class do:
     public virtual void Rotate(int directionInDegrees)
     {
          this.Direction += directionInDegrees;
     }

     public abstract void Draw();
} 

// Then use inheritance to create the classes based on this
public class Player : Character
{
     public override void Rotate(int directionInDegrees)
     {
          // Implement character specific rotate
     }

     public void Draw()
     {
          // Must implement Draw(), so that we can instantiate the class properly.
          // All methods of an abstract class must be implemented before a class is deemed
          // valid to use instantiate directly.
     }
}

public class Enemy : Character
{
   public override void Rotate()
   {
   }
}

在回答从静态类“继承”时,您不能这样做。 static 方法属于类,而不是对象的实例,所以不能被继承。它们可以被覆盖(通过使用 new 关键字来表明您正在覆盖它),但您必须为您创建的每个类实现这一点。

如果您希望能够在默认情况下覆盖方法,则必须将方法编写为非静态的。

【讨论】:

  • 谢谢你,很有帮助
【解决方案5】:

将基类中的属性标记为受保护,而不是私有...然后派生类可以访问。

【讨论】:

  • 这会带来一个问题,当我在函数中使用 Character 类时。
猜你喜欢
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多