(1) Related classes

class A … { public String show(D obj)… { return (“A and D”); } public String show(A obj)… { return (“A and A”); } } class B extends A … { public String show(B obj)… { return (“B and B”); } public String show(A obj)… { return (“B and A”); } } class C extends B … {} class D extends B … {}

(II) Question: What are the following output results?

A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); 1) System. The out. Println (a1) show (c)); (2) System. The out. Println (a1) show (d)); (3) System. The out. Println (a2) show (b)); (4) System. The out. Println (a2) show (c)); (5) System. The out. Println (a2. Show (d)); 6 System. Out. Println (b.s how (b)); All landowners System. Out. Println (b.s how (c)); End System. Out. Println (b.s how (d)); Pet-name rubyCopy the code

(3) Answer

          ①   A and A
          ②   A and A
          ③   A and D
          ④   B and A
          ⑤   B and A
          ⑥   A and D
          ⑦   B and B
          ⑧   B and B
          ⑨   A and D
Copy the code

4. Analysis

①②③ is easy to understand and generally does not make mistakes. ④⑤ why not output “B and B “? !!!!! Let’s review polymorphism.

Runtime polymorphism is one of the most powerful mechanisms for object-oriented programming code reuse, and the concept of dynamics can also be described as “one interface, many methods.” The foundation of Java’s implementation of runtime polymorphism is dynamic method scheduling, which is a mechanism for calling overloaded methods at runtime rather than at compile time.

Overriding and Overloading methods are different manifestations of Java polymorphism. Overriding Overriding is a manifestation of polymorphism between superclasses and subclasses, and Overloading is a manifestation of polymorphism within a class. If we define a method in a subclass that has the same name and parameters as its parent, we say that method is Overriding. When an object in a subclass uses this method, the definition in the subclass is called, as if the definition in the parent class is “masked” for it. If multiple methods with the same name are defined in a class with different numbers of arguments or different parameter types, they are called Overloading. The Overloaded method is the type of the returned value that can be changed.

When a superclass object references a variable that references a subclass object, the type of the referenced object, not the type of the referenced variable, determines whose member method is called, but the method being called must be defined in the superclass, that is, the method overridden by the subclass. (However, if you force a superclass to be subclassed, you can call methods that are added to the subclass but not to the superclass.)

Ok, let’s review here and get down to business! Show (O), super.show(O), this.show((super)O), super.show((super)O). Let’s see how it works.

For example, ④, a2. Show (b), a2 is A reference variable, type A, this is a2, b is an instance of B, so it looks for the show(b obj) method in class A. So this. Show ((super)O), this is still a2, where O is B, (super)O is (super)B is A, so it goes to class A to find the method show(A obj), class A has this method, but since A2 refers to an object of class B, B overrides A’s show(A obj) method, so it eventually locks to show(A obj) of class B, with the output “B and A “.

Class A = show(c obj); class B = show(c obj); class B = show(c obj); class B = show(c obj); This. Show ((super)O), this = b, O = C, (super)O = (super)C = b, so it looks for the show(b obj) method in b, and finds it, because b references an object of class B, So lock directly to show(B obj) of class B and output “B and B “.

Following the above method, other results can be correctly obtained.

The question goes on, and now let’s look at how the above analysis process reflects the meaning of the sentence in blue. It says: When a superclass object references a variable that references a subclass object, the type of the referenced object, not the type of the referenced variable, determines whose member method is called, but the method being called must be defined in the superclass, that is, the method overridden by the subclass. Take a2.show(b) for example.

A2 is A reference variable of type A that refers to an object of type B, so it is up to B to decide which method to call. Instead, call B’s show(B obj) to print “B and B “. But why do the results of the previous analysis not match? ! The problem is not to ignore the second half of the blue font, which specifies that the method being called must be defined in the superclass, that is, overridden by subclasses. Is show(B obj) defined in superclass A? No! That’s not even covered. In fact, this statement hides a message: It is still determined by the priority of method calls. It finds show(A obj) in class A, and if subclass B doesn’t override the show(A obj) method, it calls A’s show(A obj). (Since B inherits from A, it doesn’t override the method, but inherits the method from superclass A. In A sense, IT’s up to B to decide which method to call. Only the method is implemented in A); Now subclass B overrides show(A obj), so it finally locks to SHOW (A obj) of B. That’s what that sentence is all about.