Мое понимание (в С#) того, как разрешаются невиртуальные методы, заключается в том, что это зависит от типа переменной (а не от типа экземпляра).
Взгляните на код ниже.
class Program
{
static void Main(string[] args)
{
Sedan vehicle = new Sedan();
vehicle.Drive();
vehicle.Accelerate();
}
}
abstract class VehicleBase
{
public void Drive()
{
ShiftIntoGear();
Accelerate();
Steer();
}
protected abstract void ShiftIntoGear();
protected abstract void Steer();
public void Accelerate()
{
Console.WriteLine("VehicleBase.Accelerate");
}
}
class Sedan : VehicleBase
{
protected override void ShiftIntoGear()
{
Console.WriteLine("Sedan.ShiftIntoGear");
}
protected override void Steer()
{
Console.WriteLine("Sedan.Steer");
}
public new void Accelerate()
{
Console.WriteLine("Sedan.Accelerate");
}
}
Окна консоли показывают следующее:
Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
Sedan.Accelerate
Для меня это не имеет смысла, и я считаю, что многие люди запутаются. Если теперь вы объявите переменную транспортное средство типа VehicleBase, вы получите
Sedan.ShiftIntoGear
VehicleBase.Accelerate
Sedan.Steer
VehicleBase.Accelerate
Это то, что я ожидал и в предыдущем случае, потому что метод Accelerate не является виртуальным.
В предыдущем выводе (с переменным транспортным средством, типизированным как Sedan, я ожидаю, что Sedan.Accelerate будет вызываться вместо VehicleBase.Accelerate. В нынешнем виде, в зависимости от того, откуда вы его вызываете (из класса или извне) поведение меняется.
Мне кажется, что правила разрешения перегрузок для повторно введенных методов имеют приоритет, но мне трудно поверить, что это правильное/ожидаемое поведение.
Accelerate
виртуальным вVehicleBase
и переопределите его вSedan
, вы получите ожидаемое поведение. - person juharr   schedule 16.12.2012