c#帮助,这是我在一次编程面试中收到的

本文关键字:编程 一次 面试 帮助 | 更新日期: 2023-09-27 18:03:33

在最近的一次面试中,我被要求编写一个程序,该程序接受不同车辆的列表,或者其他什么,实现喇叭声接口,使用抽象类,然后为不同的车辆提供不同的喇叭声。这就是我到目前为止想出的方法,只要我独立调用这些方法,它就能很好地工作。但是,当我尝试将它们放入IEnumerable中,然后进行迭代时,它会显示抽象类的提示,而不是单个类。有人能解释一下我做错了什么吗?

    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; }
         }
    }

c#帮助,这是我在一次编程面试中收到的

在这种情况下,您需要一个抽象基类,因为这是面试的要求。然而,通常在这种情况下,如果没有人为的约束,就不应该使用基类。您可以让单个车辆直接实现接口。

一般来说,如果没有充分的理由,你不应该使用基类。一方面,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!");
    }
}

那么方法可能是:

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!"
从代码中可以看出,区别在于overriding关键字。

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