I tried the following example in C++. I understood that redefining Method4() from CA class, with Method4(int a) in CB, hides Method4() only from the visibility point of view, not from VMT perspective. Therefor, the first 2 calls in Main function are not working.
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;
}
I tried to reproduce the example in C#. To my surprise, the following call is perfectly ok.
CB b1 = new CB(); // I EXPECTED NOT TO WORK, BUT IT DOES WORK
b1.Method4();
My question is, why ? Is this a real difference between the two languages or am I missing something ?
Following your fair suggestions, I have added the C# code below:
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();
}
Not in C#.
Method4()
andMethod4(int a)
have different signatures, so for the purpose of inheritance they are like different methods.There is a concept of hiding in c#, but it is different:
In this case the called method will depend on the type of the reference. So CB.Method will "hide" CA.Method. This is made explicit by the
new
keyword, omitting this will generate a warning.