开发者

Overriding trouble

开发者 https://www.devze.com 2023-04-10 19:39 出处:网络
My code looks sort of like this, but this is a simplified version: class A: public class A{ public void testArgs(A a){

My code looks sort of 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 vo开发者_运维百科id 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 does a(new B()).testArgs(new B()) print A not B? Is there some sort of way to workaround/fix this?

edit:

Clarification:

What I really want is the superclass method to be run when it is called with an A, and the subclass method to be run when testArgs is called with a B.

Casting also isn't an option because in the actual code, unlike here, I don't know whether the result of the method call is actually B or not.

edit:

Solution:

Thanks everyone for your answers. Thanks for the clarification on overriding. I used this to implement the desired behavior.

For anyone who has 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");
    }
}


The two testArgs functions are different. One takes an A and the other takes a B. Thus, the B version doesnt override the A version. Since a(new B()) is of type A and B extends A, it is the A version that will run.

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 3 cases (because B's testArgs will override A's testArgs)


The call a(new B()) returns a new B instance of type A, when invoking testArgs() it gets called in class A and prints "A". Correct.

Should the method testArgs() override the one in super class, then the sub class version will get invoked, by means of polymorphism (but its not your case).

So to get your expected result, class B needs to properly override the method in super:

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


Debugging the problem at run-time is rather difficult. There's a very simple way to let the compiler warn you by using the anotation @Overrides

public class B extends A{

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

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

}

If I have inadvertently left out a parameter or used a wrong one then @Overrides will catch my error at compile time itself.


In your first statement, that prints "A", you could workaround the issue by casting the result of the static a() call to a B:

((B) a(new B())).testArgs(new B());
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号