Search code examples
c#overridingmethod-hiding

Need for method hiding and method overriding


Why method hiding and method overriding were developed in C#? I am not asking about their implementation. I am specifically asking about the scenarios which inventors looked to create these two things in language. Why method hiding is useful in different scenarios(code example) and why it is not. Why method overriding works well in some situations and why it is not in others. Practical Examples will be appreciated. Kindly note that I am not asking for implementation.


Solution

  • You ask why? The "why" is simple: to allow polymorphism of classes/objects.

    Let's say you want to create a class tha will represent a car and another for a truck. You may notice that both of then have a lot of properties that will be common (like they have weels, engine, weight, length and so on) and methods too (let's say "turnON" and "turnOFF" the engine, increase/decrase acceleration etc).

    What do you do? Would you write 2 classes with the exact same code, and just add the weagon for the truck?

    No, you write a "Car" class, with all the methods and properties of a car, and some of thoses properties you make then "overridable" (depends on the language on how to do it - i'm a C# programer so would be "abstract" ou "virtual", depending on the situation).

    Then the "Truck" would override the maximum speed, or the site, or say how many weels it has on the front part and the weagon, if it has a axis between or not etc.

    The hiding methods on the other hand, is when the base method canno't be overriten (since, depending on the languaga, if not "made" overridable, it can't be overriten) and so, on declaring a method on the child class, it "hides" the original one.

    How it happen? Let's say the Car class is this:

    public class Car
    {
        private double mLength;
        private int mMaxSpeed;
        public virtual double Length { get { return this.mLength; } set { if (value > 0) { this.mLength = value; } } }
        public int MaxSpeed { get { return this.mMaxSpeed; } set { if (value > 0 && value < 350) { this.mMaxSpeed = value; } } }
    }
    

    Now, on C#, the "virtual" keyword indicates that the method (or property in this case) CAN be overriten, so the lack of it means it can't. That class allows to overrite the "Length" property, but not the "MaxSpeed".

    So, when i write the Truck class, would be like this:

    public class Truck : Car
    {
        public override double Length { get { return base.Length; } set { if (value > 20.00) { base.Length = value; } } }
        public new int MaxSpeed { get { return base.MaxSpeed; } set { if (value < 100 && value > 0) { base.MaxSpeed = value; } } }
    }
    

    By doing so, the Truck class overrides the "Length", but hides the "MaxSpeed". Since Truck inherits (polymorphism) Car, it can be passed as a value to any variable of Car, so:

    Car m1 = new Car();
    Car m2 = new Truck();
    

    This works, because Truck (in our definition) is a Car. So, what's the consequence? If i create a method, that has an argument of the Car type, and i pass a Truck instance, the methods that are overriten will call (always) it's highest implementation, but the hidden methods will call the ones that are for the specific type.

    So this:

    public static void Initialize(Car vehicle)
    {
        vehicle.Length = 5.00; //if vehicle is a Car (not derivated) will be 5 if it's a truck will not set
        vehicle.MaxSpeed = 350; //will set to 350 for both, even if Truck does not allow over 100, the method called is on the car Class, not Truck
    }
    
    Initialize(new Car());
    Initialize(new Truck()); //Length won't pass (as intended on Truck class to only allow higher than 20) but MaxSpeed will pass as 350, even if Truck does not allow it
    

    Would be a problem for a hidden method (MaxSpeed), but not for the overriten method (Length). Since Length will be avaliated for it's highest implementation (it's a virtual method overriten on truck) it will always work as intented to the actual class, but MaxSpeed will be avaliated using the method write in the Car class, even if it's a Truck. It will only be avaliated as intended on the Truck class if the function/method uses Truck as an argument.