Lyrk
Lyrk

Reputation: 2000

Derived class object assigned to Base class variable

Below code, A is base class and B is a derived class. When I do A a1 = new B(); and call what a1 can see, I see that it can only see class A field because a1 is of A type so it can not see B specific members and this is what I expected too. But when I call a1.Display() it prints out B's display method. How come a1 can not see B field but can reach B's display method?

using System;    

namespace Test
{
class A
{
    public int varOfClassA = 5;

    public virtual void Display()
    {
        Console.WriteLine("I am Class A");
    }
}

class B : A
{
    public int varOfClassB = 10;

    public override void Display()
    {
        Console.WriteLine("I am class B");
    }
}

class Program
{
    static void Main(string[] args)
    {
        A a1 = new B();
        Console.WriteLine(a1.varOfClassA);  //prints out "5"
        a1.Display();   //prints out "I am class B" why???
    }
}
}

Upvotes: 0

Views: 85

Answers (1)

Zohar Peled
Zohar Peled

Reputation: 82474

That's because the method Display() is declared in B as overrides.
Every member that overrides a base class member will be executed whether the reference type is of the derived or of the base class.

When you do A a1 = new B(); what you have is an instance of B, not an instance of A.
However, since the reference is of type A, you can only access whatever methods of B that also exists in A, either inherited as is or overridden.

As a rule, in such cases, when your code executes a method on a1, the method that gets executed is the B method, since that's the type of instance you have. However, this rule does have an exception - and that is when instead of override, the method in B is declared as new. In such cases, the method (or property) of A is executed, even though your instance is of type B:

class A
{
    public virtual void Display()
    {
        Console.WriteLine("I am Class A");
    }

    public int MyIntValue { get{ return 5; } }
}

class B : A
{
    public override void Display()
    {
        Console.WriteLine("I am class B");
    }

    public new int MyIntValue { get{ return 5; } }
}

Using the above classes:

A a1 = new B();

a1.Display(); // Displays "I am class B"
Console.WriteLine(a1.MyIntValue.ToString()); // Displays "5"

You can see a live demo on rextester.

Upvotes: 1

Related Questions