Java Polymorphism Summary
The three major characteristics of object-oriented: encapsulation, inheritance, polymorphism. From a certain point of view, encapsulation and inheritance
Almost all are prepared for polymorphism two, this is our last concept and the most important knowledge point
The techniques for implementing polymorphism are:
Dynamic binding refers to judging the actual type of the reference during execution, and calling its corresponding method according to its actual type
Role: Eliminate the coupling relationship between types
definition:
Polymorphism: Only objects of different classes are allowed to respond to the same message. That is, the same message can adopt a variety of different behaviors according to the different sending objects. (The occurrence of the message is the function call)
Advantages of Polymorphism
- 1. Eliminate the coupling relationship between types
- 2. Replaceability
- 3. Scalability
- 4. Interface
- 5. Flexibility
- 6. Simplicity
Three necessary conditions for polymorphism to exist
- inherit
- rewrite
- Parent class reference points to child class object
for example:
Parent p = new Child();
When using polymorphism to call a method, first check whether the method exists in the parent class, if not, it will compile an error; if so, call the method of the same name in the subclass.
The advantage of polymorphism: it can make the program have good extension, and can carry out common processing on objects of all classes.
The following is a demonstration of a polymorphic instance, please see the comments for details:
Test.java file code:
public class Test { public static void main(String[] args) { show( new Cat()); // call show method with Cat object show( new Dog()); // call show method with Dog object Animal a = new Cat(); // Upcast a.eat(); // calling Cat's eat Cat c = (Cat)a; // downcasting c.work(); // calling Cat's work } public static void show(Animal a) { a.eat(); // Type judgment if (a instanceof Cat) { // What the cat does Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // Do what the dog does Dog c = (Dog)a; c.work(); } } } abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println( "eat fish" ); } public void work() { System.out.println( "Catch the mouse" ); } } class Dog extends Animal { public void eat() { System.out.println( "eat bones" ); } public void work() { System.out.println( "Housekeeping" ); } }
Execute the above program, the output result is:
eat fish
catch mice
eat bones
housekeeping
eat fish
catch mice
virtual method
We'll cover how the behavior of overridden methods affects polymorphism when designing classes in Java.
We have already discussed method overriding, that is, a subclass can override a method of the superclass.
When a subclass object calls an overridden method, the subclass's method is called, 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:
/* 文件名 : 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 构造函数"); this.name = name; this.address = address; this.number = number; } public void mailCheck() { System.out.println( "Mail 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; } }
Suppose the following class extends the Employee class:
Salary.java file code:
/* File name: Salary.java */ public class Salary extends Employee { private double salary; // 全年工资 public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println( "mailCheck method of class Salary" ); System.out.println( "Mail check to: " + getName() + " , salary: " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println( "Calculate salary, pay: " + getName()); return salary/52 ; } }
Now let's go through the code below and try to give 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( "Call mailCheck with reference to Salary -- " ); s.mailCheck(); System.out.println( "\nCall mailCheck with reference to Employee--" ); e.mailCheck(); } }
The result of compiling and running the above example is as follows:
Employee constructor Employee constructor Call mailCheck with Salary's quote -- The mailCheck method of the Salary class Mail check to: Employee A, salary: 3600.0 Call mailCheck with a reference to Employee -- The mailCheck method of the Salary class Mail check to: Employee B, salary: 2400.0
Example analysis
-
In the example, two Salary objects are instantiated: one refers to s using Salary and the other refers to e using Employee.
-
When s.mailCheck() is called, the compiler will find mailCheck() in the Salary class at compile time, and the JVM will call mailCheck() of the Salary class during execution.
-
Because e is a reference to Employee, when e's mailCheck() method is called, the compiler will go to the Employee class to find the mailCheck() method.
-
At compile time, the compiler validates the statement using the mailCheck() method in the Employee class, but at runtime, the Java Virtual Machine (JVM) calls the mailCheck() method in the Salary class.
The whole process above is called a virtual method call, and the method is called a virtual method.
All methods in Java behave in this way, so overridden methods can be called at runtime, regardless of the data type of the variable referenced in the source code at compile time.
How to implement polymorphism
Interface implementation, inheriting the parent class for method rewriting, and method overloading in the same class