Więcej o interfejsach wirtualnych / nowych… plus!
Wczoraj wysłałem pytanie o nowe / wirtualne / nadpisujące słowa kluczowe i wiele nauczyłem się z twoich odpowiedzi. Ale nadal mam wątpliwości.
Pomiędzy wszystkimi „pudełkami” straciłem kontakt z tym, co naprawdę dzieje się z tabelami metod tego typu. Na przykład:
interface I1 { void Draw(); }
interface I2 { void Draw(); }
class A : I1, I2
{
public void Minstance() { Console.WriteLine("A::MInstance"); }
public virtual void Draw() { Console.WriteLine("A::Draw"); }
void I2.Draw() { Console.WriteLine("A::I2.Draw"); }
}
class B : A, I1, I2
{
public new virtual void Draw() { Console.WriteLine("B::Draw"); }
void I1.Draw() { Console.WriteLine("B::I1.Draw"); }
}
class Test
{
public static void Main()
{
A a = new B();
a.Draw();
I1 i1 = new A();
i1.Draw();
I2 i2 = new B();
i2.Draw();
B b = (B)a;
b.Draw();
}
}
}
Pytanie zadane w tym ćwiczeniu to: Wypełnij tabele metod typów zgodnie z kodem i wyjaśnij dane wyjściowe wygenerowane przez uruchomienie Main ().
Moja odpowiedź brzmiała: W typie A mamy 3 metody: MInstance (), Draw () - wersja A :: Draw - i I2 :: Draw W typie B mamy 4 metody: MInstance z A, B :: Draw, I1 :: Draw i I2 :: Draw
Nie jestem zbyt pewny mojej odpowiedzi i dlatego publikuję to pytanie. Kiedy implementujemy interfejsy, utworzył on nowy slot w tabeli metod dla metod tego interfejsu? nie powinniśmy implementować I2 :: Draw także w klasie A?
Podobnie, gdy wywołujemy metodę przy użyciu zmiennej interfejsu (jak i1.Draw ()), rozumiem, że jesteśmy na dynamicznym wysyłaniu i dlatego powinniśmy przyjrzeć się typowi obiektu będącego w posiadaniu zmiennej (w tym przypadku typ A) ) i przeszukaj tabelę metod A dla metody zwanej konkretnie I1.Draw. Ale co, jeśli go nie znajdziemy? Jak mam postępować w tych przypadkach? Czy jest jakaś zasada, o której powinienem wiedzieć, aby skutecznie rozwiązać te problemy?
Przepraszam, że tak nudno z tym pytaniem, ale naprawdę muszę rozwiązać ten węzeł na głowie;)
Twoje zdrowie!