Overriding Issues

My code looks something like this, but this is a simplified version:

class A:

public class A{ public void testArgs(A a){ System.out.println("A"); } public void test(){ System.out.println("A"); } } 

class B:

 public class B extends A{ public void testArgs(B a){ System.out.println("B"); } public void test(){ System.out.println("B"); } } 

class Main:

 public class Main{ public static void main(String[] args){ a(new B()).testArgs(new B()); // prints A (new B()).testArgs(new B()); // prints B a(new B()).test(); // prints B } public static A a(B b){ return b; } } 

Why is a(new B()).testArgs(new B()) prints A, not B? Is there a workaround / fix for this?

Editing:
Clarification:

I really want the superclass method to run when it is called with A, and the subclass method that should be run when testArgs is called from B.

Casting is also not an option, because in the actual code, unlike here, I do not know if the result of the method call is actually B or not.

Editing:
Decision:

Thank you all for your answers. Thanks for the clarification about the redefinition. I used this to implement the desired behavior.
For those who have a similar problem in the future:
Change class B to

 public class B extends A{ public void testArgs(A a){ // Corrected overriding, thanks if(a instanceof B) // Check if it is an instance of B System.out.println("B"); // Do whatever else // Otherwise super.testArgs(a); // Call superclass method } public void test(){ System.out.println("B"); } } 
+6
source share
4 answers

The two functions of testArgs different. One takes A and the other takes a B Therefore, version B does not override version A Since a(new B()) is of type A and B extends A , this will be version A

There is a workaround:

 public class B extends A{ public void testArgs(A a){ // <-- note how this is A a, not B a System.out.println("B"); } public void test(){ System.out.println("B"); } } 

Then you will see B for all three cases (because B testArgs override A testArgs )

+6
source

A a(new B()) call returns a new instance of B type A , when testArgs() is called, it is called in class A and prints "A" . Right.

If the testArgs() method overrides the one in the superclass, then the version of the subclass will be called using polymorphism (but this is not your case).

So, to get the expected result, class B must correctly override the method in super:

 public class B extends A{ public void testArgs(A a){ // polymorphism would work System.out.println("B"); } ... 
+1
source

Debugging a problem at runtime is quite complicated. There's a very easy way to let the compiler warn you using anotation @Overrides

the open class B extends A {

 @Overrides public void testArgs(B a){ System.out.println("B"); } @Overrides public void test(){ System.out.println("B"); } 

}

If I accidentally rejected the parameter or used the wrong one, then @Overrides will catch my error at compile time.

0
source

In your first statement, which prints "A", you can work around the problem by exposing the result of the static call of a() to B :

 ((B) a(new B())).testArgs(new B()); 
-2
source

Source: https://habr.com/ru/post/898717/


All Articles