Java polymorphism
Polymorphism is the ability of the same behavior to have multiple different manifestations or forms.
Polymorphism is the embodiment of multiple expressions of objects.
In reality, for example, when we press the F1 key:
If the current pop-up in the Flash interface is the AS 3 help document;
If the Word Help pops up currently under Word;
If it pops up under Windows, the Windows Help and Support pops up.
The same event will produce different results when it occurs on different objects.
Three necessary conditions for the existence of polymorphism:
Inheritance
Rewrite
The parent class reference points to the subclass object
For example:
Parent p = new Child();
When calling a method using polymorphism, first check whether the parent class There is this method, if not, a compilation error occurs; if there is, then call the method of the same name in the subclass.
The benefits of polymorphism: it allows the program to be well expanded and can handle objects of all classes universally.
The following is a demonstration of a polymorphic instance. Please see the comments for details:
public class Test { public static void main(String[] args) { show(new Cat()); // 以 Cat 对象调用 show 方法 show(new Dog()); // 以 Dog 对象调用 show 方法 Animal a = new Cat(); // 向上转型 a.eat(); // 调用的是 Cat 的 eat Cat c = (Cat)a; // 向下转型 c.work(); // 调用的是 Cat 的 catchMouse } public static void show(Animal a) { a.eat(); // 类型判断 if (a instanceof Cat) { // 猫做的事情 Cat c = (Cat)a; c.work(); } else if (a instanceof Dog) { // 狗做的事情 Dog c = (Dog)a; c.work(); } } } abstract class Animal { abstract void eat(); } class Cat extends Animal { public void eat() { System.out.println("吃鱼"); } public void work() { System.out.println("抓老鼠"); } } class Dog extends Animal { public void eat() { System.out.println("吃骨头"); } public void work() { System.out.println("看家"); } }
Execute the above program, the output result is:
吃鱼 抓老鼠 吃骨头 看家 吃鱼 抓老鼠
Virtual method
We will introduce how the behavior of overridden methods affects polymorphism when designing classes in Java.
We have discussed method overriding, that is, subclasses can override methods of parent classes.
When a subclass object calls an overridden method, the method of the subclass is called, not the overridden method in the parent class.
To call an overridden method in the parent class, you must use the keyword super.
/* 文件名 : 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("邮寄支票给: " + 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 that the following class inherits the Employee class:
/* 文件名 : Salary.java */ /* 文件名 : 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("Salary 类的 mailCheck 方法 "); System.out.println("邮寄支票给:" + getName() + " ,工资为:" + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("计算工资,付给:" + getName()); return salary/52; } }
Now we read the following code carefully and try to give its output:
/* 文件名 : VirtualDemo.java */ public class VirtualDemo { public static void main(String [] args) { Salary s = new Salary("员工 A", "北京", 3, 3600.00); Employee e = new Salary("员工 B", "上海", 2, 2400.00); System.out.println("使用 Salary 的引用调用 mailCheck -- "); s.mailCheck(); System.out.println("\n使用 Employee 的引用调用 mailCheck--"); e.mailCheck(); } }
The above example compilation and running results As follows:
Employee 构造函数 Employee 构造函数 使用 Salary 的引用调用 mailCheck -- Salary 类的 mailCheck 方法 邮寄支票给:员工 A ,工资为:3600.0 使用 Employee 的引用调用 mailCheck-- Salary 类的 mailCheck 方法 邮寄支票给:员工 B ,工资为:2400.0
Example analysis
In the example, two Salary objects are instantiated: one uses Salary to reference s, and the other uses Employee to reference e.
When calling s.mailCheck(), the compiler finds that mailCheck() is in the Salary class during compilation, and the execution process JVM calls mailCheck() of the Salary class.
When calling s.mailCheck(), the Java Virtual Machine (JVM) calls the mailCheck() method of the Salary class.
Because e is a reference to Employee, when calling the mailCheck() method of e, the compiler will go to the Employee class to find the mailCheck() method.
At compile time, the compiler uses the mailCheck() method in the Employee class to verify the statement. But when running, the Java Virtual Machine (JVM) calls the mailCheck() method in the Salary class.
The entire process above is called a virtual method call, and the method is called a virtual method.
All methods in Java can be represented in this way, therefore, the overridden method can be called at runtime, regardless of the data type of the referenced variable in the source code at compile time.