2012-03-26 47 views
0

所以我对继承和接口的想法很陌生,我不知道如何实现我想要做的事情。在C#中使用继承来共享函数

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

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

那么,如何使用继承来共享玩家和AI之间的功能,同时仍然可以通过子类来访问角色类中的变量?

+2

向我们显示您的代码。 – RedFilter 2012-03-26 18:25:36

+5

*静态*播放器类?不不不。你将很难进行测试,并且难以扩展。让你的播放器类成为一个普通的类,并且你的'object reference required'错误以及测试/扩展应用程序的困难都将消失。 – tvanfosson 2012-03-26 18:27:36

+1

如果'Player'类继承'Character',它怎么能成为'static'?一个'static'类不能从除object之外的任何东西继承。 – BACON 2012-03-26 18:33:23

回答

2

实现你的基类作为一个抽象类,而不是一个静态类。静态方法将不会引用实际对象,而无法访问对象的属性或字段。

+0

谢谢,这很有帮助,我正确地认为我可以使用Player对象代替Character对象,因为它继承了它。 – Joel 2012-03-26 18:45:05

+0

我不确定“代替”是什么意思,但是如果Player从Character继承,这意味着任何Player实例也是一个Character实例。 – 2012-03-26 19:06:44

+0

是的这就是我的意思谢谢,例如我可以添加一个Player对象到一个字符列表。 – Joel 2012-03-26 19:14:04

0

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

+0

当我去函数中使用Character类时,这会引发一个问题。 – Joel 2012-03-26 18:46:08

3

如果您希望子级能够访问变量,则父级“Character”类需要将其非公共成员声明为“protected”,而不是“private”。之后,您只需使用“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++; 
    } 
} 
+0

感谢您告诉我关于base关键字的信息,我会牢记这一点。 – Joel 2012-03-26 18:46:54

2

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

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

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

+0

我没有太多时间来完成这个项目,但我已经将该页面添加到我的收藏夹中,当我有更多时间来玩这个项目时,可以查看它。谢谢 – Joel 2012-03-26 18:48:31

1

所以你要做的第一件事就是定义基类。如果你想永远不会初始化它,你可以创建一个抽象类,然后允许的属性和方法去覆盖:

// 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关键字来显示你重写它),但是你必须为你创建的每个类实现这个。

如果您想要默认覆盖方法的功能,则必须将方法编写为非静态方法。

+0

谢谢,这非常有帮助 – Joel 2012-03-26 18:52:47