简体   繁体   中英

The return types are incompatible for the inherited methods

  class A {
        public A get() { }
 }

 class B extends A {

 }

The return types are incompatible for the inherited methods, how to solve this problem ?

From JDK 5, Java allow you to alter the return type of an overridden method, as long as the new type is a subclass of the original one. This is called covariant return type . Following code will compile correctly:

class A {

    A get() {
        return new A();
    }

    void sayHello(){
        System.out.println("Hello");    
    }
}

class B extends A {

    @Override
    B get() {
        return new B();
    }

    void sayGoodbye(){
        System.out.println("Goodbye");
    }
}

class Test{
    void check(){
        B two=new B();
        two.get().sayGoodbye();
    } 
}

Remember that the return type of the overridden method should be a subclass of the return type, to allow you to call the method on A variables and get a valid A object (which is infact a B instance):

        void check(){
            A two=new B();
            A copy=two.get();
            copy.sayHello();
        }   

Use generics:

 class A<T extends A> {
        public T get() { }
 }

 class B extends A<B> {

 }

B b = new B();
B got = b.get();

I'm assuming you want to write something like B b = new B().get(); without explicit typecasting like Nikita Beloglazov suggests, though that's not an idiom that Java supports well. Eugene's answer works well enough, though that still involves a cast to T and generates an ugly compiler warning besides. Personally, I would write code more like the following:

class A {
    private A() {}

    public A get() {
        return new A();
    }
}

class B extends A {
    private B() {}

    @Override
    public A get() {
        return new B();
    }

    public B getB() {
        return (B) get();
    }
}

You still can't do B b = new B().get(); , but you can do B b = new B().getB(); , which is just as easy and a bit more self-documenting anyways, since you already know you want a B object, not just any A object. And A a = new B().get(); would create a B object, albeit one that only has access to the methods declared in A .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM