【问题标题】:C# Why can't interfaces implement methods like this? What is a workaround to solve my issue?C#为什么接口不能实现这样的方法?解决我的问题的解决方法是什么?
【发布时间】:2016-02-06 17:22:02
【问题描述】:

为什么接口不能实现这样的方法?

public interface ITargetableUnit {
        //Returns whether the object of a class that implements this interface is targetable
     bool unitCanBeTargeted(){
        bool targetable = false;
        if(this is Insect){
            targetable = (this as Insect).isFasterThanLight();
        }
        else if(this is FighterJet){
            targetable = !(this as FighterJet).Flying;
        }
        else if(this is Zombie){
            targetable = !(this as Zombie).Invisible;
        }
        return targetable;
    }
}

Insect 和 Zombie 都已经派生自基类 Creature,而 FighterJet 派生自类 Machine 但是,并非所有 Creature-s 都是可定位的并且不使用 ITargetableUnit 接口。

是否有任何解决方法可以解决我面临的问题?

【问题讨论】:

  • 接口没有行为,你要找的是抽象类
  • 因为接口不允许你提供实现。而是创建这样的层次结构,Creature -> TargetableCreature -> Insect/Ghost/ZombieCreature -> NonTargetableCreature -> WhateverIsntTargetable 但是,因为您的界面有不同的每种类型的实现,你应该只在每个类中实现接口。
  • 你应该有一个 ITargetableCreatureINonTargetableCreature 然后在 main 方法中检查其中任何一个。

标签: c# interface implementation


【解决方案1】:

就像每个人都说你不能为接口定义行为。继承特定类的接口。

public interface ITargetableUnit 
{

     bool unitCanBeTargeted();

}

public class Insect : ITargetableUnit //you can add other interfaces here
{

     public bool unitCanBeTarget()
     {
          return isFasterThanLight();
     }
}

public class Ghost : ITargetableUnit 
{
     public bool unitCanBeTarget()
     {
          return !Flying();
     }
}

public class Zombie : ItargetableUnit
{
     public bool unitCanBeTarget()
     {
          return !Invisible();
     }
}

【讨论】:

  • 作为一个挑剔的人,你不继承类中的接口,你实现它们。
  • @PrestonGuillot 正确的说法是接口实现继承。msdn.microsoft.com/en-us/library/aa664593(v=vs.71).aspx。至少我这样认为,有可能是错的。
  • @mybirthname 不,您误解了该页面的标题。它指的是从一个实现接口的类继承意味着你也实现了那个接口。
  • 可能我不想争论,我同意你们的看法。
【解决方案2】:

只是为了记录,您实际上可以这样做(不要!)但这并不是为您有权访问的代码制作扩展方法的好习惯。 Mybirthname's 解决方案是要走的路,这只是为了演示。

public interface ITargetableUnit { }


public static class ITargetableUnitExtension
{

    public static bool unitCanBeTargeted(this ITargetableUnit unit)
    {
        bool targetable = false;
        Insect insect = unit as Insect;
        if(insect != null)
            return insect.isFasterThanLight();
        FighterJet jet = unit as FighterJet;
        if(jet != null)
            return !jet.Flying;
        Zombie zombie = unit as Zombie;
        if(zombie != null)
            return zombie.Invisible;
        return false;
    }
}

【讨论】:

    【解决方案3】:

    也许你想要一个抽象类而不是一个接口?

    接口定义了类提供的方法。抽象类也可以做到这一点,但也可以为每个孩子接管一些计算。

    请注意,从技术角度来看,Insect 也可以是 Zombie

    编码愉快!

    public abstract class TargetableUnit
    {
        //Returns whether the object of a class that implements this interface is targetable
        public bool unitCanBeTargeted()
        {
            bool targetable = false;
            if (this is Insect)
            {
                targetable = (this as Insect).isFasterThanLight();
            }
            else if (this is FighterJet)
            {
                targetable = !(this as FighterJet).Flying;
            }
            else if (this is Zombie)
            {
                targetable = !(this as Zombie).Invisible;
            }
    
            return targetable;
        }
    }
    
    public class Insect : TargetableUnit
    {
        public bool isFasterThanLight()
        {
            return System.DateTime.UtcNow.Second == 0;
        }
    }
    public class FighterJet : TargetableUnit
    {
        public bool Flying { get; set; }
    }
    public class Zombie : TargetableUnit
    {
        public bool Invisible { get; set; }
    }
    

    【讨论】:

    • 扩展你的答案。添加为什么。否则这应该是一个评论。
    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 2019-05-08
    • 2022-11-02
    • 1970-01-01
    相关资源
    最近更新 更多