Другой пример полиморфного поведения: C++ и C#

Я попробовал следующий пример на C++. Я понял, что переопределение Method4() из класса CA с использованием Method4(int a) в CB скрывает Method4() только с точки зрения видимости, а не с точки зрения VMT. Поэтому первые два вызова функции Main не работают.

      class CA
{
public:
    virtual void Method1() { }
    virtual void Method2() { }
    virtual void Method3() { }
    virtual void Method4() { }
};

class CB : public CA
{
public:
    void Method1() { }
    void Method2() { }
    void Method4(int a) { }
};

int main()
{
    CB b1;
    b1.Method4();   // IT'S NOT WORKING (I EXPECTED)
    
    CB* b2 = new CB;
    b2->Method4();  // IT'S NOT WORKING (I EXPECTED)
    
    CA* a = new CB; 
    a->Method4();   // IT'S WORKING (I EXPECTED) 

    return 0;
}

Я попытался воспроизвести пример на C#. К моему удивлению, следующий вызов совершенно нормальный.

      CB b1 = new CB(); // I EXPECTED NOT TO WORK, BUT IT DOES WORK
b1.Method4();

Мой вопрос: почему? Это реальная разница между двумя языками или я что-то упускаю?

Следуя вашим справедливым предложениям, я добавил код C# ниже:

      public class CA
{
    public virtual void Method1() { }
    public virtual void Method2() { }
    public virtual void Method3() { }
    public virtual void Method4() { }
}

public class CB : CA
{
    public override void Method1() { }
    public override void Method2() { }
    public void Method4(int a) { }
}

public static void Main()
{
    CB b = new CB(); // IT'S WORKING (I DIDN'T EXPECT THIS)
    b.Method4();
}

1 ответ

Я понял, что переопределение Method4() из класса CA с использованием Method4(int a) в CB скрывает Method4().

Не на С#.Method4()иMethod4(int a)имеют разные подписи, поэтому с точки зрения наследования они похожи на разные методы.

В С# есть концепция сокрытия, но она другая:

      class CA{
    public void Method(){Console.WriteLine("CA");}
}
class CB : CA{
    public new void Method(){Console.WriteLine("CB");}
}

В этом случае вызываемый метод будет зависеть от типа ссылки. Таким образом, CB.Method «скроет» CA.Method. Это ясно выражено вnewключевое слово, если его пропустить, будет выдано предупреждение.

Другие вопросы по тегам