c#继承多态类型

本文关键字:类型 多态 继承 | 更新日期: 2023-09-27 18:17:43

从一个叫做武器的基本类开始,我打算它是多态的,如下所示:

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类定义为接口也没有成功,你不能在接口中定义方法,这正是我需要减少代码的。

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

要很好地实现这一点,最好的选择是什么?在这种情况下是否有更好的编程模式可以使用?

c#继承多态类型

是。你可以使用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
    }

您可以使用装饰器模式来扩展您的类,而不需要继承。对于这类多态问题,最好记住优先选择对象组合而不是继承原则。

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绘制。注意所有武器仍然是Weapon的实例。

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

也许另一种看待这个问题的方式是创建不同类的组合,而不是使用经典的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容器而不是"= new WeaponDrawer()")。您最终得到的是一组单一用途的类,而不是复杂的继承层次结构—它看起来像更多的代码,但您可能会发现设计更清晰,更易于维护。

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

    interface IDrawable {
       Draw(WeaponDrawer)
    }
    class DrawableWeapon : Weapon, IDrawable {
      Draw(WeaponDrawer wd){
        wd.Draw(this);
     }
    }
    class WeaponDrawer {
       Draw(Weapon weapon){
          //drawing logic here
       }
    }

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

public class DrawableWeapon<T> : Weapon where T : Weapon
{
     T _weapon;
     public void Shot()
     {
        _weapon.Shot();
     }
}

通过这种方式,你可以为每个武器实现一个不同的DrawableWeapon类。