Java Polymorphism
# Java Polymorphism
* * *
Polymorphism is the ability of an object to take on many forms.
Polymorphism means that a single interface, using different instances, can execute different operations, as shown in the following diagram:
!(#)
Polymorphism is the manifestation of an object's multiple forms.
> In real life, for example, the action of pressing the F1 key:
>
>
> * If you are currently in the Flash interface, it will pop up the AS 3 help documentation;
> * If you are currently in Word, it will pop up the Word help;
> * In Windows, it will pop up the Windows help and support.
>
>
> The same event occurring on different objects produces different results.
### Advantages of Polymorphism
* 1. Eliminates coupling between types
* 2. Substitutability
* 3. Extensibility
* 4. Interfacing
* 5. Flexibility
* 6. Simplicity
### Three Necessary Conditions for Polymorphism
* Inheritance
* Overriding
* Parent class reference pointing to a child class object: Parent p = new Child();
!(#)
class Shape{
void draw(){}
}
class Circle extends Shape{
void draw(){
System.out.println("Circle.draw()");
}
}
class Square extends Shape{
void draw(){
System.out.println("Square.draw()");
}
}
class Triangle extends Shape{
void draw(){
System.out.println("Triangle.draw()");
}
}
When calling a method using polymorphism, it first checks if the method exists in the parent class. If not, a compilation error occurs; if it does, it then calls the child class's method with the same name.
The benefit of polymorphism: it allows the program to have good extensibility and can handle objects of all classes generically.
Here is a demonstration of a polymorphism example. For detailed explanation, please see the comments:
## Test.java File Code:
public class Test{public static void main(String[]args){show(new Cat()); // Call show method with a Cat object show(new Dog()); // Call show method with a Dog object Animal a = new Cat(); // Upcasting a.eat(); // Calls Cat's eat Cat c = (Cat)a; // Downcasting c.work(); // Calls Cat's work}public static void show(Animal a){a.eat(); // Type checking if(a instanceof Cat){// What a Cat does Cat c = (Cat)a; c.work(); }else if(a instanceof Dog){// What a Dog does Dog c = (Dog)a; c.work(); }}}abstract class Animal{abstract void eat(); }class Cat extends Animal{public void eat(){System.out.println("Eating fish"); }public void work(){System.out.println("Catching mice"); }}class Dog extends Animal{public void eat(){System.out.println("Eating bones"); }public void work(){System.out.println("Guarding the house"); }}
Executing the above program, the output is:
Eating fishCatching miceEating bonesGuarding the houseEating fishCatching mice
* * *
## Virtual Functions
Virtual functions exist for polymorphism.
In Java, there is actually no concept of virtual functions. Its regular functions are equivalent to C++ virtual functions, and dynamic binding is the default behavior in Java. If you do not want a function in Java to have virtual function characteristics, you can add the final keyword to make it non-virtual.
### Overriding
We will introduce how the behavior of overridden methods affects polymorphism when designing classes in Java.
We have already discussed method overriding, which means a child class can override a method of its parent class.
When a child class object calls an overridden method, it calls the child class's method, not the overridden method in the parent class.
To call the overridden method in the parent class, you must use the keyword **super**.
## Employee.java File Code:
/* File name: Employee.java */public class Employee{private String name; private String address; private int number; public Employee(String name, String address, int number){System.out.println("Employee Constructor"); this.name = name; this.address = address; this.number = number; }public void mailCheck(){System.out.println("Mailing a check to: " + this.name + " " + this.address); }public String toString(){return name + " " + address + " " + number; }public String getName(){return name; }public String getAddress(){return address; }public void setAddress(String newAddress){address = newAddress; }public int getNumber(){return number; }}
Assume the following class inherits from the Employee class:
## Salary.java File Code:
/* File name: Salary.java */public class Salary extends Employee{private double salary; // Annual salary public Salary(String name, String address, int number, double salary){super(name, address, number); setSalary(salary); }public void mailCheck(){System.out.println("Salary class mailCheck method "); System.out.println("Mailing a check toοΌ" + getName() + " οΌwith salaryοΌ" + salary); }public double getSalary(){return salary; }public void setSalary(double newSalary){if(newSalary>= 0.0){salary = newSalary; }}public double computePay(){System.out.println("Computing pay, payingοΌ" + getName()); return salary/52; }}
Now, let's carefully read the following code and try to determine its output:
## VirtualDemo.java File Code:
/* File name: VirtualDemo.java */public class VirtualDemo{public static void main(String[]args){Salary s = new Salary("Employee A", "Beijing", 3, 3600.00); Employee e = new Salary("Employee B", "Shanghai", 2, 2400.00); System.out.println("Calling mailCheck using Salary reference -- "); s.mailCheck(); System.out.println("n Calling mailCheck using Employee reference--"); e.mailCheck(); }}
The compilation and execution result of the above example is as follows:
Employee ConstructorEmployee ConstructorCalling mailCheck using Salary reference -- Salary class mailCheck method Mailing a check toοΌEmployee A οΌwith salaryοΌ3600.0Calling mailCheck using Employee reference--Salary class mailCheck method Mailing a check toοΌEmployee B οΌwith salaryοΌ2400.0
### Example Analysis
* In the example, two Salary objects are instantiated: one using the Salary reference `s`, and the other using the Employee reference `e`.
* When `s.mailCheck()` is called, the compiler finds `mailCheck()` in the Salary class at compile time, and during execution, the JVM calls the `mailCheck()` method of the Salary class.
* `e` is an Employee reference, but the reference `e` ultimately runs the `mailCheck()` method of the Salary class.
* At compile time, the compiler uses the `mailCheck()` method in the Employee class to verify the statement, but at runtime, the Java Virtual Machine (JVM) calls the `mailCheck()` method in the Salary class.
This entire process is called virtual method invocation, and the method is called a virtual method.
All methods in Java can behave in this way, so overridden methods can be called at runtime, regardless of the data type of the reference variable in the source code at compile time.
* * *
## Implementation Methods of Polymorphism
### Method 1: Overriding:
This content has been explained in detail in the previous chapter and will not be elaborated here. For details, please visit: (#).
### Method 2: Interfaces
* 1. The most representative interface in life is the socket. For example, a three-pronged plug can be plugged into a three-hole socket because each country has its own interface rules. It might not work abroad because they have their own defined interface types.
* 2. Interfaces in Java are similar to interfaces in life. They are a collection of method signatures but without method implementations. For specific details, please see the (#) chapter.
### Method 3: Abstract Classes and Abstract Methods
For details, please see the (#) chapter.
YouTip