Why do we assign child class object to parent class reference variable?

I have the following code.

public class Parent
{
    public void Print()
    {
        Console.WriteLine ("Parent Method");
    }
}

public class Child : Parent
{
    public new void Print()
    {
        Console.WriteLine ("Child Method");
    }
}

public class Program
{
    public static void Main()
    {
        Child C = new Child();
        C.Print();
    }
}

If I run this code, I get the result "Child Method" But if I do the following, why do I get the result "Parent Method"?

public class Parent
{
    public void Print()
    {
        Console.WriteLine ("Parent Method");
    }
}

public class Child : Parent
{
    public new void Print()
    {
        Console.WriteLine ("Child Method");
    }
}

public class Program
{
    public static void Main()
    {
        Parent P = new Child();   // The only difference is this.
        P.Print();
    }
}

The only difference is as below

Child C = new Child();   
Parent P = new Child();

I thought new Child() means that we create the instance of Child class. And I thought both, C and P, are just object reference variables that hold the location of instance of Child class.
Can you correct me if I'm wrong or tell me if I miss something because I don't understand why in the above cases I get different results?

Jon Skeet
people
quotationmark

It's because you've redeclared the Print method in Child. So at compile time, P.Print() resolves to Parent.Print, but C.Print() resolves to Child.Print(). If you had a virtual method which was overridden in Child instead, they'd both print "Child Method":

public class Parent
{
    // Declare this as virtual, allowing it to be overridden in
    // derived classes. The implementation will depend on the
    // execution-time type of the object it's called on.
    public virtual void Print()
    {
        Console.WriteLine ("Parent Method");
    }
}

public class Child : Parent
{
    // Override Parent.Print, so if Print is called on a reference
    // with compile-time type of Parent, but at execution it
    // refers to a Child, this implementation will be executed.
    public override void Print()
    {
        Console.WriteLine ("Child Method");
    }
}

Related:

people

See more on this question at Stackoverflow