C#求助,我在编程面试中收到了这个

Mad*_*501 4 .net c#

在最近的一次采访中,我被要求编写一个程序,其中列出了实现鸣喇叭界面的不同车辆或其他任何车辆,使用抽象类,然后对不同的车辆使用不同的鸣喇叭.这是我到目前为止所提出的,只要我单独调用这些方法,它就能正常工作.但是当我尝试将它们放入IEnumerable中,然后迭代时,它会显示抽象类的honk,而不是单个类.谁能解释我做错了什么?

    using System;
    using System.Collections.Generic;

    namespace ConsoleHonk
    {
        class Program
        {
            static void Main(string[] args)
            {
                var myList = GetVehicles();

                //This doesn't display the correct honk
                myList.ForEach(x => x.honk());
            }

            private static List<IHonker> GetVehicles()
            {
                var myList = new List<IHonker>();    

                var myTruck = new Truck();
                var myCar = new Car();
                var myGoose = new Goose();

                myList.Add(myTruck);
                myList.Add(myGoose);
                myList.Add(myCar);

                return myList;
             }
         }

         class Goose : HonkClass
         {
             public virtual void honk()
             {
                 Console.WriteLine("Quack");
             }
         }

         class Car : HonkClass
         {

         }

         class Truck:HonkClass
         {
              public virtual void honk()
             {
                  Console.WriteLine("Honk-Honk");
             }
         }

         interface IHonker
         {
              string horn { get; set; }
              void honk();
         }

         public abstract class HonkClass:IHonker
         {
             public void honk()
             {
                  Console.WriteLine("Beep");
             }

             public string horn { get; set; }
         }
    }
Run Code Online (Sandbox Code Playgroud)

Ben*_*son 5

在这种情况下,您需要一个抽象基类,因为这是您面试的要求.但是,通常在这种情况下,如果您没有这种人为约束,则根本不应使用基类.您可以让各个车辆直接实现界面.

一般来说,如果没有充分的理由,你不应该使用基类.首先,C#支持实现多个接口,但不支持多重继承.所以,你可以有一个类实现这两个接口IHonkableISteerable,但不可两者兼得类继承HonkableBaseSteerableBase.

你的代码的问题是Honk方法没有覆盖抽象类,它们隐藏了它.行为的差异正如您所描述的:

public class HidingVehicle : HonkClass
{
    public void Honk()
    {
        Console.Writeline("Hiding honk!");
    }
}

public class OverridingVehicle : HonkClass
{
    public override void Honk()
    {
        Console.Writeline("Overriding honk!");
    }
}

public class HonkClass
{
    public virtual void Honk()
    {
        Console.Writeline("Base honk!");
    }
}
Run Code Online (Sandbox Code Playgroud)

那么方法可能是:

var myHidingVehicle = new HidingVehicle();
var myOverridingVehicle = new OverridingVehicle();
myHidingVehicle.Honk();  //"Hiding honk!"
myOverridingVehicle.Honk(); //"Overriding honk!"

HonkClass hiddenVehicle = myHidingVehicle;
HonkClass overridenVehicle = myOverridingVehcile;
hiddenVehicle.Honk(); //"Base honk!"
overridenVehicle.Honk(); //"Overriding honk!"
Run Code Online (Sandbox Code Playgroud)

从代码中可以看出,区别在于overriding关键字.

隐藏可能是故意的,但它很少需要,因为它打破了多态性.如果您确实想要隐藏,并且您确定没有更好的选项,则可以使用new方法声明中的关键字来隐藏编译器警告,并使任何读取您隐藏的代码的人都清楚.

  • 实际上需要一个抽象类,问题表明它是要求的一部分.提问者正在编写这个程序,作为面试的一部分,并测试他/她的技能. (2认同)