C#继承多态类型

时间:2014-08-13 10:16:12

标签: c# inheritance

从一个名为Weapon的基本类开始,我打算将其变为多态,如下所示:

public class Weapon
{
    // Some code..
}

public class MachineGun : Weapon
{
    // Extend the base code..
}

这些类定义了基本功能,但是它们不包含任何用于绘制武器的代码。此图仅需要在客户端应用程序中添加,服务器只需使用MachineGun类而无需可视化。

public class DrawableWeapon : Weapon
{
    // Adding draw calls and properties
}

public class DrawableMachineGun : DrawableWeapon
{
    // The problem:
    // You have no access to the properties of the original MachineGun here
}
// or..
public class DrawableMachineGun : MachineGun
{
    // Same problem, only now you miss properties of the DrawableWeapon
}

问题是丢失了MachineGun()类或DrawableWeapon()类的功能,因为C#没有多重继承。

将Weapon类定义为接口也没有成功,你不能在接口中定义方法,这正是我需要的减少代码。

我找到的唯一(部分)解决方案是方法:在单独的静态类中定义它们,在可绘制类中的每个方法调用中,也调用此静态方法。这仍然会遗漏所有属性,并导致长方法调用..

实现这一目标的最佳选择是什么?在这种情况下是否有更好的编程模式?

5 个答案:

答案 0 :(得分:4)

是。您可以使用Decorator模式:

    public class Weapon
    {
       public virtual void Shot()
       { 
          // Some code...
       }
    }

    public class MachineGun : Weapon
    {
       public override void Shot()
       { 
          // Extend base code...
       }
    }

    public class DrawableWeapon : Weapon
    {
       Weapon mWeapon;

       public override void Shot()
       { 
          mWeapon.Shot();
       }

        // Adding draw calls and properties
    }

答案 1 :(得分:0)

您可以使用装饰器模式扩展您的类而不继承。对于这种多态性问题,记住favor object composition over inheritance原则是件好事。

interface Weapon : Weapon {
    void Fire();
}

class MachineGun : Weapon {
    public override void Fire() {
        for (int i = 0; i < 5; i++) {
            // Do something
        }
    }
}

class HandGun : Weapon {
    public override void Fire() {
        // Do something
    }
}

abstract class WeaponDecorator : Weapon {
    protected Weapon weapon;

    public WeaponDecorator(Weapon weapon) {
        this.weapon = weapon;
    }

    // Implement methods by calling this.weapon's method

    public virtual void Fire() {
        weapon.Fire();
    }
}

class DrawableWeapon : WeaponDecorator {

    public DrawableWeapon (Weapon weapon) : base(weapon) {

    }

    public override void Fire() {
        PlayShakingEffect();
        base.Fire();
    }

    private void PlayShakingEffect() {

    }
}

拥有此代码,我们可以制作任何类型的Weapon drawable。请注意,所有武器仍然是Weapon的实例。

Weapon machineGun = new MachineGun();
Weapon handGun = new HandGun();

Weapon drawableMachineGun = new DrawableWeapon(new MachineGun());
Weapon drawableHandGun = new DrawableWeapon(new HandGun());

答案 2 :(得分:0)

考虑这个问题的另一种方法可能是创建不同类的组合而不是使用经典的OO继承。这强调了使用接口而不是类层次结构,其中通用代码不是继承而是被消费。实施例;

interface IDrawer 
{
    void Draw();
}
class WeaponDrawer : IDrawer // class carries out the drawing of a weapon

class Weapon : IDrawer
{
    private IDrawer : weaponDrawer = new WeaponDrawer();
    // Delegate the draw method to a completely different class.
    public void Draw()
    {
        this.weaponDrawer.Draw();
    }
}

这遵循SOLID原则,将武器的定义与绘制武器的功能分开。 (你当然可以使用IOC容器而不是&#34; = new WeaponDrawer()&#34;)。最终得到一组单一目的类而不是复杂的继承层次结构 - 它看起来更像代码,但您可能会发现设计更清晰,更易于维护。

答案 3 :(得分:0)

另一种方法,使用方法注入来允许多个抽屉实现,同时可以在需要时添加IDrawable。

    interface IDrawable {
       Draw(WeaponDrawer)
    }

    class DrawableWeapon : Weapon, IDrawable {
      Draw(WeaponDrawer wd){
        wd.Draw(this);
     }
    }

    class WeaponDrawer {
       Draw(Weapon weapon){
          //drawing logic here
       }
    }

答案 4 :(得分:0)

您可以使用泛型和装饰器模式来实现DrawableWeapon

public class DrawableWeapon<T> : Weapon where T : Weapon
{
     T _weapon;

     public void Shot()
     {
        _weapon.Shot();
     }
}

通过这种方式,您可以为您实施的每种武器获得一个独特的DrawableWeapon类。