0

disclaimer: i am totally newbie to this world of coding! in my course on learning c#, i read this article. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords.

code:

public class Car
{
    public void DescribeCar()
    {
        Console.WriteLine("Car: Four wheels and an engine.");
        ShowDetails();
    }

    public virtual void ShowDetails()
    {
        Console.WriteLine("Car: Standard transportation.");
    }
}

public class ConvertibleCar : Car
{
    public new void ShowDetails()
    {
        Console.WriteLine("ConvertibleCar: A roof that opens up.");
    }
}

ConvertibleCar myCC = new ConvertibleCar();
myCC.DescribeCar();
myCC.ShowDetails();

//Output
Car: Four wheels and an engine.
Car: Standard transportation.
ConvertibleCar: A roof that opens

Question: i expect with my understanding i should get "ConvertibleCar: A roof than opens" in my second and third line of output. what is it different when calling ShowDetails directly on the derived class, and from within a method in the base class. PS: the showdetials is set at new in the derived class.

3 Answers3

0

Because with new you effectively shadowed ShowDetails (in fact, in VB.NET there's a Shadows keyword for this). Moreover, with new you can make ShadowDetails a property!

Let's create two classes: Base and Derived:

class Base
{
    public virtual int GetInt()
    {
        return 10;
    }
}

class Derived : Base
{
    public new int GetInt()
    {
        return 11;
    }
}

Now, let's test them:

Base b;
Derived d;
int x;

b = new Derived();
d = new Derived();

x = b.GetInt(); // x = 10 [Base.GetInt()]
x = d.GetInt(); // x = 11 [Derived.GetInt()]

As you see, although b is assigned Derived, it still refers to Base.

But let's do something completely different - let's turn method into a property!

class Derived : Base
{
    public new int GetInt
    {
        get { return 11; }
    }
}

Now when we run previous test code we will see that x = 10:

x = d.GetInt(); // x = 10

But, wait, we don't have GetInt() method in Derived class! Why the code is compiled? It's simple - because we shadowed GetInt() method with GetInt property, now GetInt() is called from Base! To confuse things more, the IntelliSense doesn't show GetInt() method on d variable, but the compiler is satisfied. To get 11, you need to call property:

x = d.GetInt;

You can also turn GetInt() method into delegate:

class Derived : Base
{
    public new delegate int GetInt();
}

and use it:

Derived.GetInt getIntDelegate = () => 12;
Console.WriteLine(getIntDelegate()); // Prints 12
JohnyL
  • 6,894
  • 3
  • 22
  • 41
0

The new keyword used for the hiding base member/method. So

public new void ShowDetails()
{
    Console.WriteLine("ConvertibleCar: A roof that opens up.");
}

ShowDetails method is a new method for ConvertibleCar class and the base class ShowDetails method is completely different and it is not in the inheretance chain. Imagine that, you could define the method name like ShowDetails2 in the ConvertibleCar class. It would be same case.

Also, if you use the override keyword instead of new, the ConvertibleCar class would override the ShowDetails method.

public class ConvertibleCar : Car
{
    public override void ShowDetails()
    {
        Console.WriteLine("ConvertibleCar: A roof that opens up.");
    }
}

And output would be;

Car: Four wheels and an engine.
ConvertibleCar: A roof that opens.
ConvertibleCar: A roof that opens.
lucky
  • 12,734
  • 4
  • 24
  • 46
  • wow! this platform is awsome. reponse recieved in 15 minutes! thank you for the quick feedback, but i could not get it yet. what i understood is: if you use new keyword for a method in a derived class, that method gets preference when using the instance of that derived class. and here i am using the instance of ConvertibleCar and the variable type is also ConvertibleCar. and only when the ShowDetails() is called within the inherited baseclass method Describecar() i have the imappropriate behaviousr. – TechieSahal Dec 25 '17 at 07:01
  • Yes, you are right. As you see, "new" keyword hide the base class method. – lucky Dec 25 '17 at 07:07
0

To get your expected output, use override in place of new:

public override void ShowDetails()
{
    Console.WriteLine("ConvertibleCar: A roof that opens up.");
}

If you use new, you shadowed the ShowDetails method in the base class. This means that the derived class implementation will only be used when you call the method from a derived class variable.

override does something different. If ShowDetails is overridden, then the derived class implementation will always be used as long as the object's underlying type is the derived class, no matter the type of the variable.

This explains why the second line of output is different. The second line is produced from this line:

public void DescribeCar()
{
    Console.WriteLine("Car: Four wheels and an engine.");
    ShowDetails(); <--------
}

ShowDetails means this.ShowDetails. this is of type Car but actually refers to an object of ConvertibleCar. Since ShowDetails is shadowed, it calls the implementation of Car (because this is of type Car!)

Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • "ShowDetails means this.ShowDetails. this is of type Car but actually refers to an object of ConvertibleCar. Since ShowDetails is shadowed, it calls the implementation of Car (because this is of type Car!)" : This explanation gives a bit more clarity, thank you. but when i instantiate ConvertibleCar object, wont the ShowDetails() method, which it received by inheritance be pointing to the derived classes implimentation?. i may be not getting some basics clear on how the objects are really instantiated cand referred/used in inheritance scenarios. – TechieSahal Dec 25 '17 at 07:14
  • @TechieSahal Yes it does point to the derived class implementation. That's why you get the `ConvertibleCar`'s implementation for the third line of output. Think of it like this: when you create a new `ConvertibleCar`, the object has two `ShowDetails` method. One is the `Car`'s implementation, the other is the `ConvertibleCar`'s implementation. When the type is `ConvertibleCar`, the `Car` implementation is hidden. When the type is `Car`, the `ConvertibleCar` implementation is hidden. – Sweeper Dec 25 '17 at 07:18