I was practicing inheritance, using a test program in C# and I found out that the following statement does not throw an error:
BaseClass baseObj = new DerivedCla
I recommend you read about inheritance and Polymorphism in more detail. (here and here)
In this answer I try to keep concepts simple enough.
Why is this statement allowed and is there a situation where this statement would be useful to a programmer?
But in order to explain your question a bit lets take a look at simple and classic example of object oriented program that needs to use polymorphism.
Assume you are writing a program that needs to store some shapes and display them on screen. To achieve this you need to store all shapes in an array for example. right?
Suppose our classes are something like these:
class BaseShape
{
public virtual void Display()
{
Console.WriteLine("Displaying Base Class!");
}
}
class Circle : BaseShape
{
public override void Display()
{
Console.WriteLine("Displaying Circle Class!");
}
}
class Rectangle : BaseShape
{
public override void Display()
{
Console.WriteLine("Displaying Rectangle Class!");
}
}
And your array can be object
array. like this:
object[] shapes = new object[10];
In your application you need to write a method to display shapes.
One solution can be iterating over all shapes and call right method of exact type of shape. like this:
public static void DisplayShapes_BAD(){
foreach(var item in Shapes)
{
if(typeof(Circle) == item.GetType())
{
((Circle)item).Display();
}
if(typeof(Rectangle) == item.GetType())
{
((Rectangle)item).Display();
}
}
}
But what happens when another type of Shape
appears in application? Basically you need to modify DisplayShapes_BAD()
method to support new type of Shape
(add new if statement to body of method)
This way you break Open/Closed principle of object oriented programming. and your code is not much maintainable.
Better way to store shapes to avoid this bad method is to use array of BaseShape
. like this:
public static List<BaseShape> Shapes = new List<BaseShape>();
Here is how to add item to this list of shapes:
Shapes.Add(new Circle());
Shapes.Add(new Rectangle());
Now take a look at good implementation of DisplayShapes method.
public static void DisplayShapes_GOOD()
{
foreach(var item in Shapes)
{
item.Display();
}
}
In above method we call Display
method on item with type of BaseShape
. But how C# knows to call right method (for example circle display or rectangle display). This mechanism is Polymorphism.
Complete Code shared as Gist.
As per my understanding in java,You are trying to call object of DerivedClass by using BaseClass reference varibale baseobj and this coding scenario is totally valid because it is providing the facility of runtime polymorphism.
Before runtime polymorphism lets understand the Upcasting. When reference variable of parent class is used to refer the object of child class then it is called as Upcasting
class A{}
class B extends A{}
A obj= new B // Upcasting.
Runtime Polymorphism is a process in which a call to an overridden method is resolved at runtime rather than compile-time.
Since you are not overriding show method in derived class,You are not doing runtime polymorphism but simply upcasting and upcasting is useful when we want to resolve the calling to overridden method at runntime.
First off, the question why it's allowed, is simply because an instance of the derived class is an instance of the base class (subtype polymorphism). Same goes for being able to assign any derived class to an object variable: all .net classes derive from object in the end, so you could also have done object baseObj = new DerivedClass()
.
The goal of the type that is used for the declaration is to indicate which type of interface is being worked with (intent). If you would declare the variable as object, you'd say that only the reference is important. If you declare as BaseClass, you say that you are using an object where the properties and methods of BaseClass are important. By using BaseClass baseObj = new DerivedClass()
, you are saying you need the BaseClass functionality, but are using a DerivedClass instance to define the workings of the mapping described in BaseClass.
One reason for this could be that BaseClass is abstract (BaseClasses often are), you want a BaseClass and need a derived type to initiate an instance and the choice of which derived type should be meaningful to the type of implementation.
A reason for which it's even more often used, is because at any time, another class deriving from BaseClass can be assigned to the same variable. Consider:
BaseClass baseObj = SomeCriterium ? (BaseClass)new DerivedClass() : new AlternateDerivedClass();
The scope of the variable in the example is only in the main method, but if it were anywhere in the class, or it could be changed through a property or otherwise, by using BaseClass, anyone using your class could assign other BaseClass (derived) instance, instead of only DerivedClass (derived) instances.
Finally an example for reassigning, using an interface declaration (as far as polymorphism is concerned, the same can be applied to declaring an implemented interface instead of the class as it can to a baseclass):
IEnumerable<T> values = new List<T>();
if(needfilter)
values = values.Where(el => filtercriterium);
If values was declared as a List, the values variable could not be reused for the filtered enumeration. Basically first you say that you need the values variable only for enumeration. After that you can reassign values with another enumeration instead of only with a list.