In Java, polymorphism is divided into two types: compile-time polymorphism (overload) and run-time polymorphism (overwrite). Compilation-time polymorphism is also called pre-binding, and run-time polymorphism is also called post-binding.
Here is an example:
public class OverloadAndOverwrite { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.print("a1.print(a1): "); a1.print(a1);//Output A and A System.out.print("a1.print(b): "); a1.print(b);//Output A and A: The reason is that there is no method with parameter B in A, so the method with parameter A will be called, because B is the System.out.print("a1.print(c): "); a1.print(c);//Output A and A: The reason is that there is no method with parameter C in A, so the method with parameter A will be called, because C is inherited from B, and B is inherited from A System.out.print("a1.print(d): "); a1.print(d);//Output A and D: The reason is that because there is a method with parameter D in A, the method with parameter D will be called System.out.print("a2.print(b): "); a2.print(b);//Output B and A: The reason is that the entry is A. First, check whether there is a print method with parameter B in A. If you find that there is no, then look for a method with parameter A. Because B inherits from A. I found that such a method exists. Then check again whether this method has been rewrited in B. It is found that there is a rewrite method. Directly call the rewrite method System.out.print("a2.print(c): "); a2.print(c); //Output B and A: The reason is that the entry is A. First, check whether there is a print method with parameter C in A. If there is no, then look for whether there is a method with parameter B. Because C is inherited from B and there is no such method, then look for a print method with parameter A. Because B inherits from A. If there is such a method, then check whether this method is rewrited in B. If there is a rewrite method in B, directly call the rewritten method System.out.print("a2.print(d): "); a2.print(d);//Output A and D: The reason is that the entry is A. If there is a method with parameter D in A, check that this method has not been rewrited in B. Therefore, the result of this method in A is output; System.out.print("a2.print(a2): "); a2.print(a2);//Output B and A;The reason is that the type of a2 is A, so the print method with parameter A in A will be called, but the new one on the right of a2 is B, so because there is a method with parameter A in B, this method in B is adopted System.out.print("b.print(b): "); b.print(b);//Output B and B; Reason: The entry is B, so check whether the print function with parameter B exists in B, and if there is a direct output; System.out.print("b.print(c): "); b.print(c);//Output B and B; Reason: The entry is B, so if you see if the print function with parameter C exists in B. If you find that it does not exist, then you see if the print function with parameter B exists. If you find that it exists, and if the method is not rewritten in C, then you will directly output it; one thing to note is that you also need to check whether the print method with parameter C exists in A, because B inherits from A. If there is any, you will use this method with the result. In this way, the output result will become A and C System.out.print("b.print(d): "); b.print(d);//Output A and D; Reason: The entry is B. Although there is no print function with parameter D in B, B inherits from A. There is a print function with parameter D in A, so the output is the result of parameter D in A; } } class A { public void print(A a) { System.out.println("A and A"); } public void print(D d) { System.out.println("A and D"); } // public void print(C c) // { // System.out.println("A and C"); // } } class B extends A { public void print(B b) { System.out.println("B and B"); } public void print(A a) { System.out.println("B and A"); } } class C extends B{} class D extends C{}What needs to be explained here is:
For A a2 = new B( );
If a2 is printed separately, the print result is B@(hash code) instead of A@(hash code), but this does not mean that the type of a2 is of type B, because when we call a2.print(a2); in the above program, the output result is B and A instead of A and A (if a2 is assumed to be B, the print method with parameter B in class A should be called, because there is no such method, then the second choice to call a method with parameter A should output A and A, because B is a subclass of A).
The above is an example code analysis of rewrite and overloading. I hope it will be helpful to students studying Java.