2010-03-16 18 views
5

Tutaj bardziej podstawowe pytanie zadawane w MS wywiadzie niedawnoPolimorfizm i C#

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

Tak która funkcja jest wywoływana? Przepraszamy za literówki.

+22

Dlaczego po prostu tego nie wypróbujesz? –

+0

@Jeff: Nie ma znaczenia; B.Method1() jest nadal funkcją, która jest wywoływana. – apandit

+0

Myślę, że zgodnie z VMT (Tabela metod Vitual) zostanie wywołana najnowsza wersja zastąpionej metody. , więc może to być B.Method1() – TalentTuner

Odpowiedz

12
B.Method1(); 

pobiera nazywane ponieważ właściwie przesłania metodę wirtualną A.Method1();

5

W tym przypadku B.Method1 zostanie wywołany. Dzieje się tak, ponieważ nawet jeśli zmienna jest wpisana jako A, rzeczywisty typ instancji to B. CLR polimorficznie wywołuje wywołania do Method1 w oparciu o rzeczywisty typ instancji, a nie typ zmiennej.

2

B. Wywołanie metody Metod1() z powodu nadpisania.

3

Reguła to "element nadpisujący w najbardziej pochodnej klasie", która w tym przypadku byłaby "B".

4

Method1 z klasy B zostanie wywołana, jak widać uruchamiając poniższego programu:

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"); 
    } 
} 
1

B.Method1 nazywa ponieważ jest przesłonięta w definicji klasy.

1

Pytanie jest trochę niejednoznaczną ... ale ...

obk.method2() jest wywoływana. Z kolei wywołuje obk.Method1, który, ponieważ jest instancją B, został nadpisany przez B. Metod1. Tak więc B.Method1 jest tym, co ostatecznie zostaje wywołane.

0

Jak wszyscy inni mówią, B.Method2 zostaje wywołany. Oto kilka innych informacji, aby zrozumieć, co się dzieje:

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

Będą zarówno zadzwonić B.Method1(), ponieważ został prawidłowo nadpisane. Aby wywołać metodę A's1, musi być wywołanie base.Method1() z B (co często, ale nie zawsze jest wykonywane w implementacji metody B. Metod1).

Jeśli jednak B została określona w następujący sposób:

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

... potem za Method1() będzie nazywany ponieważ Method1 nie został faktycznie przesłonięte było ukrytych i schowany poza regułami polimorfizmu. Ogólnie rzecz biorąc, zazwyczaj jest to złe. Nie zawsze, ale upewnij się, że dobrze wiesz, co robisz i dlaczego to robisz, jeśli kiedykolwiek zrobisz coś takiego.

Po drugiej stronie, używając nowy w ten sposób tworzy również interesujące pytania dotyczące wywiadu.