OOP - Polymorphism
Polymorphism is one of 3 foundational concepts of Object Oriented Programming. Polymorphism can be translated to mean many forms. In OOP, polymorphism means that one object can be considered to have many forms. An object-reference of the base-class type can refer to either a base-class object or a child-class object. Another way to consider this is that when we have a collection of similar objects, where we refer to them with the more generalized format (base-class type object-reference variable), that variable can refer to any of the child-class objects.
In the example below, this is intuitive for us: a dog is an animal, a cat is an animal, an animal is an animal. However, a dog is not a cat, and we can'd force some instance of an animal to be strictly a cat, we would expect this to cause errors as in the example code below.
Animal[ ] animals = new Animal[3];
animal[0] = new Dog();
animal[1] = new Cat();
animal[2] = new Animal( );
Cat cat = new Cat( );
cat = new Dog( ); ///this will cause an error
cat = new Animal( ); ///this will cause an error
So, polymorphism means that child-class objects can be to be treated as their more general, base-class type, and this reflects our intuition about relationships between real-world objects. My pet, Charlie, is an instance of a dog object, but he can also be considered as an animal, which would be the more general concept, or base-class concept.
Object References
We can create an object reference variable of the base-class type, and this variable can be used to reference either a base-class object, or any object that is of a child-class type. We can imagine a set of classes, where Animal is the base-class, where Cat and Dog would be child-classes that extend Animal. Below are examples using default constructors to demonstrate using base-class object references to refer to child-class object instances. It is important to note that the reverse is not true, you can not use an object-reference of the Child-class type to refer to a base class object.
Array of base-class object references
Animal[] animals= new Animal[3] //array of base-class object references
animals[0] = new Animal( ); //base-class object
Dog dog1 = new Dog( ); //child-class object
animals[1] = new Dog( ); //base-class type object reference, child-class object
Cat cat1 = new Cat( );
animals[2] = new Cat( );
//IMPORTANT: Note that these will cause errors:
cat1 = animals[0]; //child-class reference-type, base-class object
cat1 = dog1; //child class reference-type
Over-riding Methods
OOP Polymorphism means that when a child-class object executes a method, then the 'system' will determine whether to execute a child-class method or a base-class method, by examining the child class definition to see if the method has been implemented in the child-class so that it over-rides the base-class method. Method over-riding allows us to treat objects using the more general, base-class, references, but that the 'system' will determine the run-time type of each object instance, and determine whether a base-class or child-class method will be executed. If a method has not been over-ridden in a child class, the child-class object can still call any method specified in the base-class, the child-class 'gets' everything in the base-class 'for free' when it extends the base-class to become a child-class.
Object Oriented Design
Polymorphism should be considered when designing classes with inheritance relationships. Only methods defined in the base-class can be called on using base-class object references, even if the object refers to a child-class object. Therefore, UML class diagrams provide a graphical representation to aid design and use of OOP classes and objects.
UML Diagram of Inheritance Relationships

The diagram above shows a base-class: Creature, and 3 Child classes: Zombie, Cat, Fish
When creating object reference variables, we specify the data-type of the variable, and this impacts the methods that can be called for the object.
Example 1: Base-class object-reference variable:
Creature creature = new Fish( 10, 10, f );
This object can call any methods that are specified in the base-class.
creature.display();
creature.move( );
creature.attack( creature );
This object can not call any methods that are not specified in the base-class, even if they are specified in the child-class for the object's actual data-type:
//this will cause an error:
creature.glubGlub( );
Example 2: Child-class object-reference variable:
Fish fish = new Fish( 10, 10, f);
This object can call any methods specified in either it's base-class, or it's own class (Fish)
fish.attack( fish ); //no error doing this
fish.glubGlub( );
Object Oriented Design - Add methods to the base-class to provide access to specialized behavior in child-classes.
When designing classes, as in the example above, we should identify any specialized behavior that will be exhibited by any child-class and create a method in the base-class that represents the generalized behaivor.
Example: We have a child-class: Fish, where the fish has a specialized behavior: glubGlub( ). Let's assume that can be considered as a more generalized concept: makeNoise( ), where other child classes might also share this behavior. If we define the method: makeNoise( ) in the base-class, then, within the Fish class, we can over-ride makeNoise( ), and call the glubGlub( ) method within makeNoise( ). Then any base-class object can call makeNoise( ), if the object happens to be a Fish, child-class object, it will have it's glubGlub( ) behavior executed.
//within the Creature class: provide makeNoise( )
void makeNoise( ){
println("some creatures will make special noises by overriding this method");
}
//Within the Fish class: over-ride makeNoise( )
void makeNoise( ){
this.glubGlub( );
}
The image below shows an improved object-oriented design, so that all methods implemented in the base-class can be called by an object with a base-class type reference variable, and if the object is a child-class object, it'll have specialized behavior because it has provided an over-ride for methods where it has special logic to be executed

Last updated
Was this helpful?