The frequently asked questions are about the overloading method and overriding method.
The code is as follows: |
Copy code |
Public class MethodOverrideVsOverload { Public boolean equals (MethodOverrideVsOverload other ){ System. out. println ("MethodOverrideVsOverload equals method reached "); Return true; } Public static void main (String [] args ){ Object o1 = new MethodOverrideVsOverload (); Object o2 = new MethodOverrideVsOverload (); MethodOverrideVsOverload o3 = new MethodOverrideVsOverload (); MethodOverrideVsOverload o4 = new MethodOverrideVsOverload (); If (o1.equals (o2 )){ System. out. println ("objects o1 and o2 are equal "); } If (o3.equals (o4 )){ System. out. println ("objects o3 and o4 are equal "); } } } |
A. The output result is:
MethodOverrideVsOverload equals method reached
Objects o3 and o4 are equal
What concepts have this question explored?
• In Java, a class can only be inherited from one class (that is, a single inheritance structure). If the class inherited is not explicitly indicated, then it automatically inherits from the Object.
• Most non-final object class methods will overwrite the quilt class (overridden ):
Public boolean equals (Object obj); // make note of this method
Public int hashCode ();
Public String toString ();
• The overload method works during compilation (for example, static binding), and the rewrite method works at runtime (for example, dynamic binding ). Static binding means that the JVM decides the class or method to call during compilation. During dynamic binding, the JVM decides to call classes or methods at runtime. Dynamic binding design is the basis of polymorphism. Learn more about compile time and runtime.
• The method for overwriting the parent class in the subclass must follow the following rules:
The parameter is unchangeable (Translator's note: includes the parameter type and number ).
The return type is unchangeable except for the covariant return type or its subtype (covariant (subtype) returns ).
Fewer exceptions can be thrown in the exception subclass, but no checked exceptions not defined in the parent class can be thrown.
The access permission is looser than the corresponding method in the parent class.
Call the runtime (that is, dynamic binding), and decide the specific method to call based on the object type.
Now, let's look back at the above code. The "equals (MethodOverrideVsOverload other)" method in the MethodOverrideVsOverload class does not overwrite the "public boolean equals (Object obj)" method in the Object class. This is because it violates the parameter rules. One of them is the MethodOverrideVsOverload type, and the other is the Object type. Therefore, the two methods are reload relations (occur at compilation), rather than rewrite relations.
Therefore, when o1.equals (o2) is called, the public boolean equals (object obj) method in the Object class is actually called. This is because both o1 and o2 are of the Object type during compilation, while the equals (... ) The method is to compare the memory address (for example, Object @ 235f56 and Object @ 653af32), so false is returned.
When o3.equals (o4) is called, the equals (MethodOverrideVsOverload other) method in the MethodOverrideVsOverload class is actually called. This is because both o3 and o4 are of the MethodOverrideVsOverload type during compilation, so the above results are obtained.
What can I do next?
Q. How can I solve the problem above?
A. In Java 5, annotations are added, including compile time annotations @ override, to ensure that the method correctly overrides the parent class method. If an annotation is added to the code above, the JVM will throw a compilation error.
Therefore, the solution is to add the @ override annotation to the boolean equals (MethodOverrideVsOverload other) method of the MethodOverrideVsOverload class. In this case, an error is thrown during compilation, prompting the developer that a method does not correctly rewrite the parent class method. Then, you also need to modify the parameters of the method from Object to MethodOverrideVsOverload, as follows:
The code is as follows: |
Copy code |
View Code Public class MethodOverrideVsOverload { @ Override Public boolean equals (Object other ){ System. out. println ("MethodOverrideVsOverload equals method reached "); Return true; } Public static void main (String [] args ){ Object o1 = new MethodOverrideVsOverload (); // during compile time o1 is of type Object // During runtime o1 is of type MethodOverrideVsOverload Object o2 = new MethodOverrideVsOverload (); // during compile time o2 is of type Object // During runtime o2 is of type MethodOverrideVsOverload MethodOverrideVsOverload o3 = new MethodOverrideVsOverload (); // o3 is of type MethodOverrideVsOverload // During both compile time and runtime MethodOverrideVsOverload o4 = new MethodOverrideVsOverload (); // o4 is of type MethodOverrideVsOverload // During both compile time and runtime If (o1.equals (o2 )){ System. out. println ("objects o1 and o2 are equal "); } If (o3.equals (o4 )){ System. out. println ("objects o3 and o4 are equal "); } } } |
Output:
The code is as follows: |
Copy code |
MethodOverrideVsOverload equals method reached Objects o1 and o2 are equal MethodOverrideVsOverload equals method reached Objects o3 and o4 are equal |