Здесь еще один основной вопрос, который задают в MS недавно взять интервью
class A {
public virtual void Method1(){}
public void Method2() {
Method1();
}
}
class B:A {
public override void Method1() { }
}
class main {
A obk = new B();
obk.Method2();
}
Таким образом, какая функция вызвана? Извините за опечатки.
B.Method1();
вызывается, потому что правильно переопределяет виртуальный метод A.Method1();
В этом случае вызывается B.Method1
. Это потому, что даже если переменная имеет тип A
, фактический тип экземпляра - B
. CLR полиморфно отправляет вызовы к Method1
на основе фактического типа экземпляра, а не типа переменной.
Вопрос немного двусмысленный ... но ...
вызывается obk.method2 (). В свою очередь, он вызывает obk.Method1, который, поскольку он является экземпляром B, был переопределен B.Method1. Итак, в конечном итоге вызывается B.Method1.
Как все уже сказали, вызывается B.Method2. Вот несколько других сведений, чтобы вы поняли, что происходит:
((A)B).Method2();
B.Method2();
В обоих случаях будет вызван B.Method1(), потому что он был правильно переопределен. Для того чтобы вызвать Method1 из A, из B должен быть сделан вызов base.Method1() (что часто, но не всегда, делается в реализации B.Method1).
Если, однако, B был определен таким образом:
class B:A {
new public void Method1() { }
... тогда будет вызван Method1() A, потому что Method1 на самом деле не был переопределен, он был скрыт и спрятан вне правил полиморфизма. В общем, обычно так делать не стоит. Не всегда, но убедитесь, что вы хорошо знаете, что вы делаете и почему вы это делаете, если вы когда-нибудь сделаете что-то подобное.
С другой стороны, использование new таким образом позволяет задать несколько интересных вопросов на собеседовании.
B.Method1 вызывается, потому что он переопределен в определении класса.
Метод1
из класса B
будет вызван, в чем вы можете убедиться, выполнив приведенную ниже программу:
class Program
{
static void Main(string[] args)
{
var b = new B();
b.Method2();
Console.ReadLine();
}
}
class A
{
public virtual void Method1()
{
Console.WriteLine("Method1 in class A");
}
public void Method2()
{
Method1();
}
}
class B : A
{
public override void Method1()
{
Console.WriteLine("Method1 in class B");
}
}
Правило гласит "переопределение члена в наиболее производном классе", которым в данном случае будет "B".