Polymorphism
Polymorphism (from greek for diversity, complex shape) is a concept in object-oriented programming that allows an identifier of object to accept objects of different classes at runtime.
The most common use of polymorphism in OOP occurs when a superclass reference is used to refer to a subclass object. At runtime, the system decides whether to call the method of the superclass or the overwritten method of the subclass:
Class Student inherits from class Person. Method info() is overridden.
public class Person { protected String name; public Person(String name) { this.name = name; } public void info() { System.out.println("Name of person: " + name); } }
public class Student extends Person{ public Student(String name) { super(name); } public void info() { System.out.println("Name of student: " + name); } }
Now an identifier of type of superclass can take both types of object, an object of class Person or an object of class Student. But not vice versa!
When the assignment of this object happens at runtime and not at compile time, so-called polymorphism causes the call the method of the superclass or the overwritten method of the subclass:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; public class Main { public static void main(String[] args) { // NO POLYMORPHISM, early binding -> the call of the respective method of Person/Student // was already defined at compile time. Person p = new Person("p"); Student s = new Student("s"); p.info(); s.info(); Person p2 = (Person) s; p2.info();Student s2 = (Student)p;// would throw an ClassCastException at run-time // because Person is a part of Student and not vice versa. Person cannot be cast to Student. // POLYMORPHISM, late binding -> The decision to call the respective method of Person/Student // is made at runtime. ArrayList<Person> persons = new ArrayList<>(); char ch; String name = ""; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); do { System.out.print("Create person -> p\tstudent -> s? "); try { ch = br.readLine().charAt(0); if (ch == 'p' || ch == 's') { System.out.print("\tName: "); name = br.readLine(); } } catch (IOException e) { System.out.println("Error: " + e); break; } if (ch == 'p') persons.add(new Person(name)); if (ch == 's') persons.add(new Student(name)); } while (ch == 'p' || ch == 's'); for (Person person : persons) { person.info(); if (person instanceof Person) System.out.println("I am a person"); if (person instanceof Student) System.out.println("I am a student"); } } }
Name of person: p // early binding -> NO POLYMORPHISM
Name of student: s
Name of student: s
Create person -> p student -> s? p // late binding -> POLYMORPHISM 1. creation of a person
Name: person
Create person -> p student -> s? s // 2. creation of a student
Name: student
Create person -> p student -> s? q // quit
Name of person: person
I am a person // the person is an instance of Person
Name of student: student
I am a person // the student is both - a person and a student, which makes sense
I am a student