Exact difference between overriding and hiding
Asked Answered
E

9

18

Can anybody tell the working of overriding and hiding in terms of memory and references.

class A
{
    public virtual void Test1() { //Impl 1}
    public virtual void Test2() { //Impl 2}
}
class B  : A
{
    public override void Test1() { //Impl 3}
    public new void Test2() { Impl 4}
}

static Main()
{
    A aa=new B() //This will give memory to B
    aa.Test1(); //What happens in terms of memory when this executes
    aa.Test2(); //-----------------------SAME------------------------
}

Here memory is with class B but in the second statement aa.Test2 class A's method will be called. Why is it? If B has memory then B's method should be called (in my point of view).

Any link / exercise that describes this fundamental very deeply and completely will be a big help.

Elysia answered 15/6, 2012 at 7:30 Comment(5)
Also can anybody tell me the use case of method hiding?Elysia
Because aa is A and not B. Try with ((B)aa).Test2()Sop
@Sop Correct but memory is with B not A ?Elysia
You should explicitly cast to B to get access to B's methods. aa is still an A.Sop
Dup of C# keyword usage virtual+override vs. new, Difference between shadowing and overriding in C#?, Overloading,Overriding and Hiding?, and many others.Guggle
A
32

Take a look at this answer to a different question by Eric Lippert.

To paraphrase (to the limits of my comprehension), these methods go into "slots". A has two slots: one for Test1 and one for Test2.

Since A.Test1 is marked as virtual and B.Test1 is marked as override, B's implementation of Test1 does not create its own slot but overwrites A's implementation. Whether you treat an instance of B as a B or cast it to an A, the same implementation is in that slot, so you always get the result of B.Test1.

By contrast, since B.Test2 is marked new, it creates its own new slot. (As it would if it wasn't marked new but was given a different name.) A's implementation of Test2 is still "there" in its own slot; it's been hidden rather than overwritten. If you treat an instance of B as a B, you get B.Test2; if you cast it to an A, you can't see the new slot, and A.Test2 gets called.

Apperceive answered 15/6, 2012 at 7:57 Comment(3)
This is quite excellent way to understand the concept of polymorphism. However, I don't know whether this slotting thing actually happens in memory or not. Thanks a lot Rawling....Elysia
@AkkiJ I'd imagine they are literal items in memory somewhere, something like Func/Actions, but I couldn't say for sure.Apperceive
@AkkiJ: virtual tables exist once per each subtype (class), they are not instantiated every time an object is instantiated. If your base class contains a virtual method, each instance of that class will contain the type handle (pointer to its virtual table) and (if such exist) instance fields. If you don't have any fields in your class, its instance will always contain exactly 12 bytes.Plyler
P
6

To add to @Rawling's answer, practical examples could be shown using an example such as this:

class Base
{
    // base property
    public virtual string Name
    {
        get { return "Base"; }
    }
}

class Overriden : Base
{
    // overriden property
    public override string Name
    {
        get { return "Overriden"; }
    }
}

class New : Base
{
    // new property, hides the base property
    public new string Name
    {
        get { return "New"; }
    }
}

1. Overriding

In case of the overriden property, base class' virtual method's slot is replaced by a different implementation. Compiler sees the method as virtual, and must resolve its implementation during run-time using the object's virtual table.

{
    Base b = new Base();
    Console.WriteLine(b.Name); // prints "Base"

    b = new Overriden();
    // Base.Name is virtual, so the vtable determines its implementation
    Console.WriteLine(b.Name); // prints "Overriden"

    Overriden o = new Overriden();
    // Overriden.Name is virtual, so the vtable determines its implementation
    Console.WriteLine(o.Name); // prints "Overriden"
}

2. Hiding

When a method or a property is hidden using the new keyword, the compiler creates a new non-virtual method for the derived class only; base class' method remains untouched.

If the type of the variable is Base (i.e. only contains the virtual method), its implementation will be resolved through the vtable. If the type of the variable is New, then the non-virtual method or property will be invoked.

{
    Base b = new Base();
    Console.WriteLine(b.Name); // prints "Base"

    b = new New();
    // type of `b` variable is `Base`, and `Base.Name` is virtual,
    // so compiler resolves its implementation through the virtual table
    Console.WriteLine(b.Name); // prints "Base"

    New n = new New();
    // type of `n` variable is `New`, and `New.Name` is not virtual,
    // so compiler sees `n.Name` as a completely different property
    Console.WriteLine(n.Name); // prints "New"
}

3. Summary

If a part of your code accepts the base type, it will always use the virtual table during run-time. For most OOP scenarios, this means that marking a method as new is very similar to giving it a completely different name.

4. Object sizes after instantiation

Note that instantiating any of these types doesn't create a copy of the virtual table. Each .NET object has a couple of bytes of header and a pointer to the virtual table of table of its type (class).

Regarding the new property (the one which is not virtual), it is basically compiled as a static method with thiscall semantics, meaning that it also doesn't add anything to the size of the instance in memory.

Plyler answered 15/6, 2012 at 8:42 Comment(2)
If you are more interested in memory internals of .NET than compiler behavior, then check this great link: .NET Framework Internals: How the CLR Creates Runtime Objects, and in this case Object Instance and Method table chapters. It may seem like a lengthy read, but every .NET programmer should read it at some point.Plyler
I have all the time and interest to read detailed discussions about the actual working of .NET. Thanks a lot for the excellent explanation and important links.Elysia
N
3

Already answered at here

Overriding is the definition of multiple possible implementations of the same method signature, such that the implementation is determined by the runtime type of the zeroth argument (generally identified by the name this in C#).

Hiding is the definition of a method in a derived type with a signature identical to that in one of its base types without overriding.

The practical difference between overriding and hiding is as follows:

Hiding is for all other members (static methods , instance members, static members). It is based on the early binding . More clearly , the method or member to be called or used is decided during compile time.

•If a method is overridden, the implementation to call is based on the run-time type of the argument this. •If a method is simply hidden, the implementation to call is based on the compile-time type of the argument this.

Here are some samples : Example # 1. and Example # 2

Nullification answered 15/6, 2012 at 7:39 Comment(0)
E
1

Test1() method in class A and test1() method in class B will executes according to MethdOverriding.

Test2() method in class A and test2() method in class B will executes according to Method Hiding.

In method Overriding the child class members will execute, and in Method Hiding the Parent class members will execute.

Elyseelysee answered 11/7, 2014 at 9:48 Comment(0)
G
0

Deducting from the code provided you should have B:A.

You can hide a method in case when you want create your own implementation of the (say) method of the base class, which can not be overriden, cause, say, it's not virtual.

In my expirience, I used hiding mostly for debug purposes.

For example when I don't know who sets the property of some 3rd prt component, whom code is not available to me. So what I do is:

  • create a child class from the component
  • hide the property of interest with new keyword
  • put the breakpoint in set
  • and wait when it will be hit.

Sometimes, very useful and helps me get information in fast way, especially in first stage when you're learning new components, frameworks, libraries.. whatever.

Guesstimate answered 15/6, 2012 at 7:33 Comment(0)
N
0

Put simply when overriding a method or property the override method must have the same signature as the base method. When hiding this is not required, the new object can take any form as shown below

// base
    public int GrossAmount { get; set; }

    // hiding base
    public new string GrossAmount
    {
        get;
        set;             
    }
Normalize answered 15/6, 2012 at 7:36 Comment(0)
P
0

By hiding a method or a property you are simply stating that you want to stop such method being polymorphic when you have an object of that type. Additionally hidden methods are called in a non polymorphic way so to call these method type has to be know at compile time, as it was a simply non virtual method.

Perales answered 15/6, 2012 at 7:47 Comment(0)
F
0
 public class BaseClass
    {
      public void PrintMethod()
      {
       Console.WriteLine("Calling base class method");
      }
     }
     public class ChildClass
     {
      public new void PrintMethod()
      {
       Console.WriteLine("Calling the child or derived class method");
       }
      }
      class Program
      {
       static void Main()
       {
        BaseClass bc = new ChildClass();
        bc.PrintMethod();
        }
       }

Method Hiding is that when Base Class reference variable pointing to a child class object. It will invoke the hidden method in base Class.

Where as, When We declare virtual method in the base class. We override that method in the derived or child class. Then Base Class reference variable will call the derived class method. This is called Method Overriding.

Frobisher answered 7/5, 2015 at 8:5 Comment(0)
B
0
class Base {
    int a;
    public void Addition() {
        Console.WriteLine("Addition Base");
    }
    public virtual void Multiply()
    {
        Console.WriteLine("Multiply Base");
    }
    public void Divide() {
        Console.WriteLine("Divide Base");
    }
}

class Child : Base
{
    new public void Addition()
    {
        Console.WriteLine("Addition Child");
    }
    public override void Multiply()
    {
        Console.WriteLine("Multiply Child");
    }
    new public void Divide()
    {
        Console.WriteLine("Divide Child");
    }
}
class Program
{        
    static void Main(string[] args)
    {
        Child c = new Child();
        c.Addition();
        c.Multiply();
        c.Divide();

        Base b = new Child();
        b.Addition();
        b.Multiply();
        b.Divide();

        b = new Base();
        b.Addition();
        b.Multiply();
        b.Divide();
    }
}

Output : -

Addition Child

Multiply Child

Divide Child

Addition Base

Multiply Child

Divide Base

Addition Base

Multiply Base

Divide Base

At the time of overriding the compiler checks the object of the class but in in hiding compiler only checks the reference of the class

Burundi answered 28/7, 2017 at 7:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.