5

I have a litte confusion regarding method overriding and the validity of OOP priciples. I know everything regarding sealing, shadowing, overriding, virtual etc. but I came across a scenario, that just confused me. Suppose I have:

class classA
{

    public virtual void sayhello()

      {
        Console.WriteLine("hello I'm A");
    }

};

class classB :classA
{
    public override void sayhello()
    {
        Console.WriteLine("hello I'm B");
    }

};
class Program
{
    static void Main(string[] args)
    {

        classB a = new classB();
        a.sayhello();
    }
}

According to everything I studied so far, a method declared as virtual or abstract (in abstract class) can be overriden using override keyword in child class. according to this, above code works perfect. When I remove the virtual keyword, and then try to override the method using override keyword, then compiler gives error as:

cannot override inherited member 'inheritence.classA.sayhello()' because it is not marked virtual, abstract, or override

and then i removed the override key word, from child class, and provided the implementation as:

class classB :classA
{
    public void sayhello()
    {
        Console.WriteLine("hello I'm B");
    }

};

In this case, the method could be overrided. I'm able to override the method, which is not virtual or abstract. so, my question is:

1. Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.

2. Why am I allowed to override the method this way? which is not even marked virtual?

3. Removing virtual keyword from classA method, it gave me the feeling of sealed method in classA, when I tried to override that method in classB. (as I mentioned the compiler error earlier). If i remove virtual, so that the child class may not override it, then WHY could the child class cleverly override it, removing its override keyword? Is this ONLY the case, sealed keyword is designed for?

sth
  • 222,467
  • 53
  • 283
  • 367
Zeeshan
  • 2,884
  • 3
  • 28
  • 47
  • 2
    You performed a concept called method hiding http://msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx – Samuel Dec 21 '13 at 09:49
  • yea, but isn't it violating oop priciples? let's say, classA did not want to let it's method be hidden? Or why do we then use **new** keyword for shadowing, when we can simply hide it? – Zeeshan Dec 21 '13 at 09:54
  • @O.R.Mapper Yes it will. because OP is having instance typed as `classB` – Sriram Sakthivel Dec 21 '13 at 09:54
  • @SriramSakthivel: Oh, right. Got confused with the variable name being `a`. – O. R. Mapper Dec 21 '13 at 09:55
  • 2
    In your last case you should see a warning that the method you introduced in `classB` hides the one in `classA`. That is not overriding. It is just two unrelated methods with the same name. Avoid that; it leads to confusion. – Jeppe Stig Nielsen Dec 21 '13 at 09:57
  • 1
    @JeppeStigNielsen Yea, I noticed that warning :) is there anyway, I can make sure, the child classes do NOT do this? – Zeeshan Dec 21 '13 at 10:00
  • If you are writing the child classes, you can ask the compiler to treat warnings as errors. Then it won't translate your code if you do that. – Jeppe Stig Nielsen Dec 21 '13 at 10:03

5 Answers5

3

I will like to tell you that you gave hidden the parent child method not overridden.
One more thing you might have not noted doing the same is seeing WARNING because in warning section it will be clearly mentioned that,

Warning 'line number' 'classB .sayhello' hides inherited member 'classA.sayhello'. Use the new keyword if hiding was intended.

Your question,

Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.

No surely it did not violate the OOP principle as you have hide the base class method.

Why am I allowed to override the method this way? which is not even marked virtual?

Because C# not only supports overriding but also method hiding and A hiding method has to be declared using the new keyword. For More Information read dotnet_polymorphism and overriding-vs-method-hiding

Is this ONLY the case, sealed keyword is designed for?

From MSDN sealed sealed keyword is designed to prevent derivation of class and to negate the virtual aspect of the virtual members.

  • When applied to a class, the sealed modifier prevents other classes from inheriting from it.
  • sealed modifier can be only applied to a method or property that overrides a virtual method or property in a base class. This prevent further overriding specific virtual methods or properties but it can never stop method-hiding. Read Non-overridable method for more information
Community
  • 1
  • 1
Deepak Bhatia
  • 6,230
  • 2
  • 24
  • 58
  • Thank you :) can you make me clear, isn't hidding, indirectly equal to overriding? why would parent class let that happen, when it did not want it method to be overriden? – Zeeshan Dec 21 '13 at 10:15
  • 1
    @Zeeshan see the edited answer for more information and you can find some more interesting ideas about `sealed` with `override` at [Sealed Overriden](http://stackoverflow.com/questions/797530/c-sharp-is-it-possible-to-mark-overriden-method-as-final) – Deepak Bhatia Dec 21 '13 at 10:26
  • you mean, I cannot shadow the sealed method? – Zeeshan Dec 21 '13 at 10:33
1
  1. Did it not violate the OOP principle? since I'm able to override the method, which is not marked as virtual in parent.

You did not override the parent method you have hidden the parent method.

so you can never access the parent method from the child class object as it was hidden by your child class method sayhello().

2.Why am I allowed to override the method this way? which is not even marked virtual?

because you can hide the parent methods with child implemetation.

Sudhakar Tillapudi
  • 25,935
  • 5
  • 37
  • 67
  • Thank you. Can I be sure, that my child classes do NEVER hide the methods of parent this way? because it seems a dangerous thing. – Zeeshan Dec 21 '13 at 10:04
  • 1
    @Zeeshan: the only possibility is Checking the warning : `Warning 1 'classB.sayhello()' hides inherited member 'classA.sayhello()'. Use the new keyword if hiding was intended. ` – Sudhakar Tillapudi Dec 21 '13 at 10:13
1

I think this comes from C++ implementation, which used slicing (What is object slicing?).

While C# resembles mostly Java, in some cases (this one and the existence of value types) it follows the C++ way.

The reasoning after this is that, since your code calls method sayhello from an A variable, the programmer expects the logic of A.sayhello to be executed. It does not break OOP principles, since you are executing an A.sayhello implementation (so it must match the A.sayhello contract).

The difference with Java is not OOP vs not OOP, but that Java uses late binding (the actual method to be executed is decided at runtime based in a actual instance) while C# uses early binding (the method is decided at compile time) unless the method is virtual.

Personally I prefer late binding, while C# approach is correct from an OOP point of view, I find that usually the more specialized method should be used.

Community
  • 1
  • 1
SJuan76
  • 24,532
  • 6
  • 47
  • 87
  • Also check http://stackoverflow.com/questions/367411/early-binding-vs-late-binding-what-are-the-comparative-benefits-and-disadvanta – SJuan76 Dec 21 '13 at 10:05
  • very nice explaination, and differentiation :) – Zeeshan Dec 21 '13 at 10:20
  • please notice that **a** is an object of classB. sorry for not making it confusing. – Zeeshan Dec 21 '13 at 10:22
  • when the parent class method is not marked **virtual** and the requirement is to override it in child class, then the ONLY thing I can do is **hidding**. rite? I mean, to obtain the overriding effect – Zeeshan Dec 21 '13 at 10:27
1

Well, it's quite simple in the end:

  1. When overriding virtual methods, the concrete methods are resolved at runtime.
  2. When using the new keyword (or leaving it out completely), you're doing a static replacement operation at compile time based on the type information that is available in your code.

These are two totally different things.

Thomas Weller
  • 11,631
  • 3
  • 26
  • 34
  • Thanks. did you mean that when I'm hiding method's implementaion, the resolution in this case is actually being at runtime? – Zeeshan Dec 21 '13 at 10:10
  • No, the other way round: Overriding means resolving at runtime, method hiding happens at compile time. – Thomas Weller Dec 21 '13 at 10:12
  • is overriding ALWAYS resolved at runtime? even when it's static binding, and 0% polymorphysmic effect in code? – Zeeshan Dec 21 '13 at 10:17
  • 1
    Yes, always. That's because virtual methods can always be overridden from outside later on. You cannot predict that on compile time. The entire concept of OO-polymorphism assumes that there is no concrete type information available at compile time. – Thomas Weller Dec 21 '13 at 10:22
  • when the parent class method is not marked **virtual** and the requirement is to override it in child class, then the ONLY thing I can do is **hidding**. rite? – Zeeshan Dec 21 '13 at 10:26
  • 1
    Right. _Overriding_ a non-virtual method is just not possible. You only can _hide_ it (but then you will loose polymorphism). – Thomas Weller Dec 21 '13 at 10:33
1

What you did is method hiding (as others already explained).

If you really want to do it you should add new keyword in method definition to make warning disappear and also as a documentation. So that other developers looking at your code know that you did it on purpose.

Piotr Perak
  • 10,718
  • 9
  • 49
  • 86