3
  class A {
        public A get() { }
 }

 class B extends A {

 }

返回类型与继承的方法不兼容,如何解决这个问题?

4

3 回答 3

1

从 JDK 5 开始,Java 允许您更改被覆盖方法的返回类型,只要新类型是原始类型的子类即可。这称为协变返回类型。以下代码将正确编译:

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();
    } 
}

请记住,被覆盖方法的返回类型应该是返回类型的子类,以允许您在 A 变量上调用该方法并获取有效的 A 对象(实际上是 B 实例):

        void check(){
            A two=new B();
            A copy=two.get();
            copy.sayHello();
        }   
于 2012-04-27T19:26:52.990 回答
0

我假设您想编写B b = new B().get();类似 Nikita Beloglazov 建议的没有显式类型转换的东西,尽管这不是 Java 支持的习语。尤金的回答效果很好,尽管这仍然涉及强制转换T并产生一个丑陋的编译器警告。就个人而言,我会编写更像以下的代码:

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();
    }
}

你仍然不能做B b = new B().get();,但你可以做B b = new B().getB();,这同样容易,而且更容易自我记录,因为你已经知道你想要一个B对象,而不仅仅是任何A对象。并且A a = new B().get();会创建一个 B 对象,尽管它只能访问在A.

于 2012-04-27T18:57:18.500 回答
0

使用泛型:

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

 class B extends A<B> {

 }

B b = new B();
B got = b.get();
于 2012-04-27T18:07:18.447 回答