Question

I can understand the basic object slicing ,but sometimes it's becoming much confusing when we come to examples like that one

using System;
class A
{
   public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
   public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
   new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
   public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
   static void Main() {
      D d = new D();
      A a = d;
      B b = d;
      C c = d;
      a.F();
      b.F();
      c.F();
      d.F();
   }
}

OUTPUT :

B.F
B.F
D.F
D.F

i want to know how the "f()" function of class B is reached

D d = new D();
A a = d;
a.F();

while if it were :

A a = new A();
a.F()
//The result would be => A.F  

however in the first part the "a" has a run time object of "d" so one might think it would be "D.F" as output ,so how it came along D and c and and B so the right output is "B.F" Please help me to work this out

Was it helpful?

Solution

When you use new to define a method with the same name as a base class' method, you hide the base class' implementation. (This is almost always a bad idea, but very occasionally necessary.)

When you reference a class with a hidden method like this, it's not an override. Because of this, the variable type that you use to refer to the object will dictate which version of the method you'll get.

When you reference your new D() through either a or b, you're referencing it as a type that doesn't know about the new version of the method. Therefore both of these calls use the most derived version of the method that they do know about. There is no override for B.F() in either C (because it's new) or D (because it only overrides the method in C). Therefore, B.F() is called in both of these cases.

When you reference the class through c or d, the overridden method in D is used, as you would expect.

OTHER TIPS

Well, AMAIK, your question is essentially not about object slicing. It's more about the difference between using new, virtual and override keywords.

I'll bring forward a more understandable example. Consider this code:

public class Animal
{
    public virtual void Sleep()
    {
        Console.WriteLine(@"I'm an animal, and I want to sleep.
        I just close my eyes");
    }
}

public class Mammal : Animal
{
    public override void Sleep()
    {
        Console.WriteLine(@"I'm a mammal, thus basically an animal.
        Therefore, I both close my eyes, and need a warm place to sleep");
    }

    public bool HasBreasts
    {
        get
        {
            return true;
        }
    }
}

public class Human : Mammal
{
    public new virtual void Sleep()
    {
        Console.WriteLine(@"I'm a human. 
        I'm so proud that I don't consider myself as an animal. 
        I sleep in a cozy place, 
        and I need a lot of money to sleep well");
    }

    public virtual void FallInLove();
}

public class Worker : Human
{
    public override void Sleep()
    {
        Console.WriteLine(@"I'm a worker, and I'm under poverty line. 
        I have to work hard, 
        and I really don't know what they mean by a good sleep");
    }

    public override void FallInLove()
    {
        Console.WriteLine(@"What is love? 
        I need bread to survive. 
        I'm in the bottom-most level of Mozlow's pyramid of needs.");
    }
}

Now let's analyze each keyword. Since a Worker is basically and essentially a human, thus it HasBreasts and also it can FallInLove(). But wait a minute. A worker (no offense, just a funny example) has no money to fall in love. Then a worker might override this very behavior, and forget about love.

On the other hand, all animals can sleep. They only close their eyes to sleep. However, since Mammals are hot blooded, they need a warm place. So they extend their ancestor's habit of sleeping.

But human on the other hand, defined a completely new level of sleeping. He wants a revolution against his ancestors. He doesn't want to be known as an Animal, so he redefines Sleep() from scratch.

Now based on explanations of @DanPuzey, you can read rest of the story. It makes sense in the real-world.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top