Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

The term polymorphism can be defined as “having many forms.” A polymorphic reference is a reference variable that can refer to different types of objects at different points in time. The specific method invoked through a polymorphic reference can change from one invocation to the next.

At some point, the commitment is made to execute certain code to carry out a method invocation. This commitment is referred to as binding a method invocation to a method definition. In many situations, the binding of a method invocation to a method definition can occur at compile time. For polymorphic references, however, the decision cannot be made until run time. The method definition that is used is based on the object that is being referred to by the reference variable at that moment. This deferred commitment is called late binding or dynamic binding. It is less efficient than binding at compile time, because the decision must be made during the execution of the program. This overhead is generally acceptable in light of the flexibility that a polymorphic reference provides.

Code Example

Using the classes we have created: Publication, Magazine, and Textbook

Code Block
languagejava
/* Driver to demonstrate polymorphism using the Textbook and Magazine Class 
 */
 
import java.time.LocalDate;
import java.util.ArrayList; // import the ArrayList class
import java.time.LocalDate; // for a date varaible 

public class Demo4 {
	public static void main(String[] args) {
	
		//create an Array List of Publications
		ArrayList<Publication> myPublications = new ArrayList<Publication>();
		
		//now add some Magazines and textbook to the Publication ArrayList		
		//adding textbooks
		myPublications.add(new TextBook("Learn Java", "Bart Simpson", 759, "8th Edition", "Computer Science") ); 
		myPublications.add(new TextBook("Learn C++", "Fred Flintstone", 759, "7th Edition", "Computer Science") ); 
		
		//create a date
		LocalDate myDate = LocalDate.of(2022, 8, 30); 
		
		//adding magazines
		myPublications.add(new Magazine("Time Magazine", "Time Life Publisher", 83, "Monthly", myDate)); 
		myPublications.add(new Magazine("Alamo College Magizine", "ACCC", 65, "Quarterly", myDate)); 
		
		//now iterate through the array and display the magazines and textbooks 
		for(Publication pPubs : myPublications)
		{
			System.out.println(pPubs.PrintInformation());
		}		
		
	}//end of Main

}//end of class 

The given Java code is a demonstration of Polymorphism using an ArrayList of objects that belong to the Publication parent class and its child classes TextBook and Magazine.

  1. ArrayList<Publication> myPublications = new ArrayList<Publication>(); : This line creates an ArrayList named myPublications which can hold objects of type Publication. Because TextBook and Magazine are both subclasses of Publication, they can also be added to this ArrayList due to polymorphism.

  2. The code then adds instances of TextBook and Magazine to the myPublications ArrayList using the add() method.

    • myPublications.add(new TextBook("Learn Java", "Bart Simpson", 759, "8th Edition", "Computer Science")); This line creates a new TextBook object with given values and adds it to the myPublications ArrayList.

    • LocalDate myDate = LocalDate.of(2022, 8, 30); This line creates a new LocalDate object named myDate.

    • myPublications.add(new Magazine("Time Magazine", "Time Life Publisher", 83, "Monthly", myDate)); This line creates a new Magazine object with given values and adds it to the myPublications ArrayList.

  3. The code then uses a for-each loop to iterate over the myPublications ArrayList. Each time through the loop, it calls the PrintInformation() method on the current object.

    • for(Publication pPubs : myPublications) { System.out.println(pPubs.PrintInformation()); } This is the for-each loop that iterates through each Publication object in myPublications. pPubs holds the current Publication object during each iteration. The PrintInformation() method is then called on pPubs and its return value is printed to the console.

This demonstrates polymorphism because the PrintInformation() method that gets called depends on whether pPubs is a TextBook or Magazine object. This decision is made at runtime based on the actual type of the object, even though pPubs is declared as a Publication (the parent class of both TextBook and Magazine).

...

Panel
panelIconId1f4a1
panelIcon:bulb:
panelIconText💡
bgColor#E3FCEF

Polymorphism in programming is a concept that's a bit like having a universal remote control. Just as this one remote can interact with your TV, sound system, and DVD player in different ways, polymorphism allows a single interface to be used with different underlying forms (data types).

Here's how it works in simple terms:

  1. Many Forms: The word "polymorphism" comes from Greek words meaning "many forms." In programming, it refers to the ability of a single function or method to work in different ways depending on the object it is acting upon.

  2. Example - Shapes: Imagine you have a program with different shapes (like circles, squares, triangles). All of these shapes might have a method called draw, but the way you draw each shape is different. Polymorphism allows you to call the draw method on any shape without needing to know the specific type of shape. The correct draw method is called depending on whether it's a circle, a square, or a triangle.

  3. Types:

    • Compile-Time Polymorphism (Method Overloading): This is like having multiple versions of the same remote button, each doing something a bit different depending on what you're trying to control (TV, DVD player, etc.). In programming, this means having multiple methods with the same name but different parameters.

    • Run-Time Polymorphism (Method Overriding): This is like the remote automatically adjusting its function based on the device it's pointing at. In programming, this is when a subclass overrides a method of its superclass, and the method to execute is determined at runtime.

  4. Why Use Polymorphism? It makes the program more flexible and scalable. Just like the universal remote simplifies controlling different devices, polymorphism simplifies and unifies the interaction with different objects in a program.

In summary, polymorphism in programming allows methods to do different things based on the object they are acting upon, much like a universal remote control can operate different devices in ways specific to each device. This leads to more flexible and easily maintainable code.

Polymorphism is a fundamental concept in programming, particularly within the paradigm of object-oriented programming (OOP). It describes the ability of different objects to be accessed through the same interface, allowing for different underlying forms (data types) to be manipulated in a uniform manner.

Conceptual Overview:

  1. Polymorphism comes from Greek words meaning "many forms."

  2. It allows objects of different classes to be treated as objects of a common superclass.

  3. The specific form or class of an object is less important than the fact that it has the interface expected; the details of its actual type can remain hidden.

Types of Polymorphism:

  • Ad-hoc Polymorphism: This is achieved through function overloading or operator overloading.

  • Parametric Polymorphism: This allows a function or a data type to be written generically, so it can handle values identically without depending on their type. This is often used in generic programming.

  • Subtype Polymorphism (or Inclusion Polymorphism): This is the form most commonly referred to as "polymorphism" in OOP. It allows a function to use objects of different types at different times, depending on the type of the object it is referencing at that time.

Practical Example:

Consider a simple class hierarchy where a superclass Shape has a method draw(). Subclasses like Circle, Square, and Triangle each implement draw() differently. If you have a list of Shape objects, you can iterate over them and call draw() on each one, and the correct version of the method is called for each object, whether it's a Circle, Square, or Triangle.

Real-world Analogy

Imagine a simple video game with different types of characters like warriors, archers, and mages. Each character type has a unique way of attacking: warriors might use swords, archers use bows and arrows, and mages use magic spells. However, from the game's perspective, they are all game characters and can perform an "attack" action.

Here, polymorphism allows you to treat all these different character types as general "game characters" and call the "attack" action on them, without needing to know their specific types. The appropriate attack action (sword slash, arrow shot, or magic spell) will be carried out based on the actual type of character, even though your code simply calls the same "attack" method on a general "game character."

Benefits

  1. Code Reusability: You can write code that works on the superclass type, but it will work with any subclass type, providing they follow the expected contract (like method names and parameters).

  2. Code Maintainability: Polymorphism promotes cleaner, more intuitive, and more maintainable code. You can add new subclasses with little or no modification to existing code that uses the superclass.

  3. Flexibility: Polymorphism allows for code that is more flexible and can handle a range of inputs, reducing the complexity of conditional statements.

  4. Abstraction: It allows for abstract design, where you can define a common class for a group of related classes.

By understanding and using polymorphism, you can write more flexible, maintainable, and reusable code.

At some point, the commitment is made to execute certain code to carry out a method invocation. This commitment is referred to as binding a method invocation to a method definition. In many situations, the binding of a method invocation to a method definition can occur at compile time. For polymorphic references, however, the decision cannot be made until run time. The method definition that is used is based on the object that is being referred to by the reference variable at that moment. This deferred commitment is called late binding or dynamic binding. It is less efficient than binding at compile time, because the decision must be made during the execution of the program. This overhead is generally acceptable in light of the flexibility that a polymorphic reference provides.

...

Example

Code Block
languagejava
/* 
 * Polymorphism  Late binding 
 */

// Animal class - this is the base class 
 class Animal {	 
  public void animalSound()
  {
	  System.out.println("The animal makes a sound");
  } 
   
  // Regular method
  public void sleep() {
    System.out.println("Zzz");
  }
} //end of Animal Base Class
 
 /* *********************************
  * Derived Classes
  *********************************** */

//Subclass (inherit from Animal)
//Notice how we define the Abstract method animalSound declared in the super class 
class Cat extends Animal {
	public void animalSound() {
	// The body of animalSound() is provided here
	System.out.println("The cat says Meow");
	}
} //end of Cat Class

//Subclass (inherit from Animal)
class Dog extends Animal {
	public void animalSound() {
	// The body of animalSound() is provided here
	System.out.println("The dog says Woof");
	}
} //end of Dog class

//Subclass (inherit from Animal)
class Cow extends Animal {
	public void animalSound() {
	// The body of animalSound() is provided here
	System.out.println("The dog says Moo");
	}
} 


/*
 * ******************************
 * Main Program to demo polymorphism
 * Author Dr. Kevin Roark
 * ******************************
 */

public class Demo5Demo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		 Animal myAnimal = new Animal();  // Create a Animal object
		 myAnimal.animalSound();
		 myAnimal.sleep();
		 
		 //now create an Animal and make it a Dog
		 Animal myDog = new Dog();
		 myDog.animalSound();
		 myDog.sleep();
		 
		 //now create an Animal and make it a Cat
		 Animal myCat = new Cat();
		 myCat.animalSound();
		 myCat.sleep();
		 
		 Animal myCow = new Cow();
		 myCow.animalSound();
		 myCow.sleep();
		 
		 //demonstration of instanceof
		 if(myCat instanceof Cat)
		 {
			 System.out.println("This is a cat!");
		 }
		 if(myCat instanceof Animal)
		 {
			 System.out.println("This is a Animal!");
		 }

	}

}

...