代码之家  ›  专栏  ›  技术社区  ›  mezoid

为什么重写方法只在我实现接口之后发生?

  •  4
  • mezoid  · 技术社区  · 16 年前

    我一直在阅读《有效地使用遗留代码》一书,并且一直在玩弄通过创建伪代码覆盖单元测试中难以测试的方法的概念。我把一个我认为有效的例子放在一起,结果它的表现与我预期的不同。我想我刚刚在对继承和方法重载在C#中的工作原理的理解上发现了一个漏洞,我想知道是否有人能帮助我理解这里发生了什么。

    我有以下界面:

    public interface IAnimal
    {
        void MakeSound();
        void Move();
    }
    

    public class Dog : IAnimal
    {
    
    public void MakeSound()
    {
        Console.WriteLine("Woof");
    }
    
    public void Move()
    {
        Console.WriteLine("Moved");
    }
    
    }
    

    当我按如下方式使用该类时:

    IAnimal myanimal = new Dog();
    myanimal.MakeSound();
    myanimal.Move();
    

    汪汪 感动的

    public class FakeDog : Dog
    {
        public void MakeSound()
        {
             Console.WriteLine("Bark");
        }
    }
    

    当我按如下方式使用该类时:

    IAnimal myanimal = new FakeDog();
    myanimal.MakeSound();
    myanimal.Move();
    

    我得到以下输出: 汪汪

    我一直以为会是: 吠叫 感动的

    但是,如果我让FakeDog类实现动物接口并使用它:

    public class FakeDog : Dog, IAnimal
    {
        public void MakeSound()
        {
             Console.WriteLine("Bark");
        }
    }
    

    吠叫 感动的

    3 回复  |  直到 14 年前
        1
  •  4
  •   Jon Skeet    16 年前

    在第一种情况下,您正在创建一个新方法 兽皮 IAnimal.MakeSound new 关键字使其显式。

    重新实施 IAnimal . 实现接口不需要 override 关键字(尽管如果语言设计者 要求)。

    为了避免重新实现接口,您可以 MakeSound Dog FakeDog . 在这一点上,只涉及一个可能的解决方案,而且一切都更容易理解。我尽可能避免重新实现和方法隐藏。

        2
  •  2
  •   Rob Fonseca-Ensor    16 年前

    (很抱歉回答了一个问题,但您可能真的觉得这个实验很有用)当您实现dog时会发生什么情况,如下所示:

    public class Dog : IAnimal
    {
    
    public virtual void MakeSound()
    {
        Console.WriteLine("Woof");
    }
    
    //...
    

        3
  •  1
  •   Darin Dimitrov    16 年前

    你需要申报 MakeSound 方法为 virtual Dog 阶级和 推翻 它在 FakeDog 类别:

    public class Dog : IAnimal
    {
        public virtual void MakeSound()
        {
            Console.WriteLine("Woof");
        }
    
        public virtual void Move()
        {
            Console.WriteLine("Moved");
        }
    }
    
    public class FakeDog : Dog
    {
        public override void MakeSound()
        {
            Console.WriteLine("Bark");
        }
    }