Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#继承多态类型_C#_Inheritance - Fatal编程技术网

C#继承多态类型

C#继承多态类型,c#,inheritance,C#,Inheritance,从一个名为武器的基本类开始,我希望它是多态的,如下所示: public class Weapon { // Some code.. } public class MachineGun : Weapon { // Extend the base code.. } 这些类定义了基本功能,但是它们不包含任何绘制武器的代码。此图形只需添加到客户端应用程序中,服务器只需使用MachineGun类,无需可视化 public class DrawableWeapon : 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()类或DrawableWearm()类的功能,因为C#没有多重继承

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

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

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

是。您可以使用以下模式:

    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
    }
对。您可以使用以下模式:

    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
    }

您可以使用decorator模式扩展类,而无需继承。记住这类多态性问题的原理是很好的

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() {

    }
}

您可以使用decorator模式扩展类,而无需继承。记住这类多态性问题的原理是很好的

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() {

    }
}

也许看待这一点的另一种方式是创建不同类的组合,而不是使用经典的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();
    }
}

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

也许看待这一点的另一种方式是创建不同类的组合,而不是使用经典的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();
    }
}

这遵循坚实的原则,将武器的定义与绘制武器的功能分开。(当然,您可以使用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
       }
    }

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

    interface IDrawable {
       Draw(WeaponDrawer)
    }

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

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

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

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

     public void Shot()
     {
        _weapon.Shot();
     }
}
公共类DrawableWearm:武器,其中T:武器
{
T_武器,;
公众虚空射击()
{
_武器。射击();
}
}

通过这种方式,您可以为每个实现的武器获得一个不同的DrawableWearm类。

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

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

     public void Shot()
     {
        _weapon.Shot();
     }
}
公共类DrawableWearm:武器,其中T:武器
{
T_武器,;
公众虚空射击()
{
_武器。射击();
}
}

通过这种方式,您可以为实现的每种武器获得一个不同的DrawableWearm类。

我认为您必须使基类可绘制,并使其成为武器的基类。那么你有可画的面具你说的画是什么意思?取消嗅探或渲染到屏幕?如果你问我,去除武器气味的动作是由武器的载体来完成的,而不是武器本身。在这种情况下,您不需要多重继承。通过在客户端版本中绘制元素在屏幕上可视化武器。我编辑这篇文章是为了让这一点更清楚。你应该添加更多的细节(在Drawable和MachineGun中有几个方法/字段的示例)。根据您的场景有多复杂,您可能能够通过使用接口+扩展方法来减少一些代码重复,但有时这是不可能的。我认为您必须使基类可绘制,并使其成为武器的基类。那么你有可画的面具你说的画是什么意思?取消嗅探或渲染到屏幕?如果你问我,去除武器气味的动作是由武器的载体来完成的,而不是武器本身。在这种情况下,您不需要多重继承。通过在客户端版本中绘制元素在屏幕上可视化武器。我编辑这篇文章是为了让这一点更清楚。你应该添加更多的细节(在Drawable和MachineGun中有几个方法/字段的示例)。根据您的场景有多复杂,您可以通过使用接口+扩展方法来减少一些代码重复,但在某些情况下这是不可能的。我认为您应该使用泛型来实现drawableweaponThanks类,因为如果机枪覆盖射击,您无法从drawableweaponThanks调用覆盖!通过覆盖某些属性,我能够获得所需的效果。作为对上述评论的回答,mWeapon.Shot()在调用基函数之前调用MachineGun的override函数。我认为您应该使用泛型来实现drawableweaponThanks类,因为如果机枪override Shot,则无法从drawableweaponThanks调用override!通过覆盖某些属性,我能够获得所需的效果。作为对上述注释的回答,mWeapon.Shot()在调用基函数之前调用MachineGun的override函数