Полиморфизм и с # - PullRequest
       9

Полиморфизм и с #

5 голосов
/ 16 марта 2010

Вот еще один базовый вопрос, недавно заданный в интервью 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(); 
}

Так какая функция вызывается? Извините за опечатки.

Ответы [ 8 ]

12 голосов
/ 16 марта 2010
B.Method1();

вызывается, потому что он корректно переопределяет виртуальный метод A.Method1();

5 голосов
/ 16 марта 2010

В этом случае B.Method1 вызывается. Это потому, что, хотя переменная имеет тип A, фактический тип экземпляра - B. CLR полиморфно отправляет вызовы Method1 на основе фактического типа экземпляра, а не типа переменной.

4 голосов
/ 16 марта 2010

Method1 из класса 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"); 
    } 
} 
3 голосов
/ 16 марта 2010

Правило - "переопределяющий член в наиболее производном классе" , который в этом случае будет "B".

2 голосов
/ 16 марта 2010

B.Method1 () вызывается из-за переопределения.

1 голос
/ 16 марта 2010

Вопрос немного двусмысленный ... но ...

obk.method2 () вызывается. В свою очередь, он вызывает obk.Method1, который, поскольку он является экземпляром B, был переопределен B.Method1. Итак, B.Method1 - это то, что в конце концов получит название.

1 голос
/ 16 марта 2010

B.Method1 вызывается, потому что он переопределен в определении класса.

0 голосов
/ 16 марта 2010

Как и все остальные, B.Method2 вызывается. Вот еще несколько сведений, чтобы вы поняли, что происходит:

((A)B).Method2();
B.Method2();

Они оба будут вызывать B.Method1 (), потому что он был правильно переопределен. Чтобы вызвать метод Method1 от A, должен быть вызов base.Method1 () из B (который часто, но не всегда, выполняется в реализации B.Method1).

Если, однако, B был определен следующим образом:

class B:A {
new public void Method1() { }

... тогда метод А1 () будет вызван, потому что метод1 фактически не был переопределен, он был скрыт и спрятан вне правил полиморфизма. В общем, обычно это плохо. Не всегда, но убедитесь, что вы очень хорошо знаете, что вы делаете и зачем вы это делаете, если вы когда-нибудь делаете что-то подобное.

С другой стороны, использование new таким образом создает некоторые интересные вопросы для интервью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...