-2

If I am having base class like below:

class A
{
  public virtual void print()
    {
      Console.WriteLine("Base class method");   
      Console.Read();
    }

}

And derived class which inherited from base class like below:

class B : A
{
    public override void print()
    {
        Console.WriteLine("Child Class Method");
        Console.Read();
    }
}

Main method to to create the objects is below:

class Method
{
    static void Main(string[] args)
    {
       A obj=new B();
       obj.Print();  
    }
 }

The above code will invoke the child class method. But even if I created object like B obj=new B() and did 'obj.Print()', the same output would be rendered.

So what is the use creating object like A obj=new B() and calling method like above?

On the other hand, if I change derived class method as below:

public new void print()
{
    Console.WriteLine("Child Class Method");
    Console.Read();
}

And if do A obj=new B(), then obj.print() will invoke the base class method. The same if I do A obj=new A() and obj.print().

So what is the point of having a base class reference variable pointing to a derived reference class object and invoking the members like above? At which scenarios should this logic be used?

Abhi
  • 785
  • 1
  • 10
  • 19

3 Answers3

1

You have a method with this signature:

void Print(ICollection<A> objects)
{
    foreach(var obj in objects)
    {
        obj.print();
    }
}

the print will use either B implementation or A implementation (for A it could be another child C that does not new the print method) reading: https://stackoverflow.com/a/6162547/6460438

Community
  • 1
  • 1
Greg
  • 69
  • 4
0

The reason you'd do this is for polymorphism. For example, you might have a method:

void Process(A item)
{
  item.print();
}

Now you can say:

B b = new b();
Process(b);

And although the method takes an A it will dispatch to the correct implementation.

Sean
  • 60,939
  • 11
  • 97
  • 136
0

The guiding principle here is that, when you're dealing with objects, you should use the broadest type that meets your needs (The least-derived type). This is sometimes expressed as "Code to an interface, not an implementation." Don't get confused by that terminology, though. Coding against a base class is also just fine, if that's the type that meets your needs.

The reason is simple: It simplifies later maintenance and refactoring, and makes the code easier to reuse elsewhere. The type of a variable makes promises about how that variable will work. It's easier to make your functions more widely applicable if you make those promises wider. When you choose a base class for your variable type, you can be more confident about changing the underlying implementation later.

In your example, if I code against A, but create an instance of B, I can be pretty confident that later, when I add a class C : A { ... } that I could use it in this function if I wanted to. If I code against B directly, that's harder to prove.

As for how those keywords relate to this:

virtual is used to mark a method as being one that a subclass can redefine (in fact, we probably expect subclasses to redefine it, at least occasionally). You use this when there's a reasonable default implementation that will work most of the time, but still want to give a subclass a way to potentially optimize the function for its own use.

abstract is used to indicate that this class expects a subclass to "fill in" some missing details. You use this when there's no way to know how to implement a method, but you know you'll need the method. abstract methods are always virtual. If a class defines any abstract methods, then the class itself must be abstract and you can't actually create an instance of it. In my own experience, I use abstract more than virtual.

override is used to indicate that this class is actually (re-)defining the behavior of the parent class.

new in this context is slightly special. Since a parent class must explicitly grant permission to its subclasses to redefine a method, we can't just override wherever we want. That's usually a good thing, but sometimes, you need to step outside the rules. (That jerk library author "forgot" to make a method virtual and we have a major optimization that we need to perform...) That's what new is for. It gives us a way around the normal inheritance rules should they get in the way. You should use this very sparingly.

Ian McLaird
  • 5,507
  • 2
  • 22
  • 31