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#支持实现多个接口,但不支持多重继承。所以你可以让一个类同时实现IHonkable
和ISteerable
两个接口,但不能同时继承HonkableBase
和SteerableBase
两个类。你的代码的问题是,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
关键字来隐藏编译器警告,并使任何阅读您隐藏的代码的人都清楚。