Search code examples
c#subclasssuperclass

Superclass behaviour doesn't apply as expected to the Penguin object


Any thoughts on why altitude is not 5 at the end of this program? So I have a Penguin class deriving from Birds, and in Birds class I have a check on whether the birds is flightless, and based on that I reset the given altitude to 0 or keep the provided altitude. Supposing penguins can fly (isFlightless=false), Penguin.ArrangeBirdInPatterns(p); should trigger the ArrangeBirdInTheSky, which it does, and then the altitude should be the one I provided (=5), not zero.

My VS crashed and I'm using online fiddlers, hard to debug.

using System;

public class Bird {
    public double altitude;
    public bool isFlightless;
    public virtual void setLocation(double longitude, double latitude) {
    }
    public virtual void setAltitude(double altitude) {
        this.altitude = altitude;
    }

    public void ArrangeBirdOnGround()
    {
        setAltitude(0);
    }
    public void ArrangeBirdInTheSky()
    {
        setAltitude(altitude);
    }
    public static void ArrangeBirdInPatterns(Bird b)
    {
        if(b.isFlightless)
        {
            b.ArrangeBirdOnGround();
        }
        else
        {
            b.ArrangeBirdInTheSky();
        }
    }

};

public class Penguin : Bird
{
    public override void setAltitude(double altitude) {

    }
}


public class Program
{

    public static void Main()
    {
        Bird p = new Penguin();
        p.setAltitude(5);
        p.isFlightless = false;
        Penguin.ArrangeBirdInPatterns(p);
        Console.WriteLine(p.altitude);  //// returns 0. why not 5

    }
}

Also, why can't I call it like: ArrangeBirdInPatterns(p); if I remove static from the ArrangeBirdInPatterns definition?


Solution

  • You're calling Penguin's setAltitude, which does nothing. The type of p is Bird, but the type of the value contained there is Penguin, which overrides Bird.setAltitude, so that's what gets called.

    You can look into the differences between virtual, override, and new keywords for more info on the different ways to subclass.