为什么允许在子类中更改抽象方法的返回类型?
abstract class Animal {
public abstract Animal assing(Animal a);
}
class Lizard extends Animal {
@Override
public Lizard assing(Animal a) {
return new Lizard();
}
}
class Chicken extends Animal {
@Override
public Chicken assing(Animal a) {
return new Chicken();
}
}
而不允许更改参数类型:
abstract class Animal {
public abstract void foo(int x);
}
class Lizard extends Animal {
// compiler error
// the type Lizard must implement the inherited abstract method Animal.foo(int)
public void foo(float x) {
}
}
class Chicken extends Animal {
@Override
public void foo(int x) {
}
}
答案 0 :(得分:10)
因为overriden methods
允许来自 java 1.5+版本的co-variant returns。
另外,当您在具体类中更改参数类型时,您基本上会声明一个全新的方法,该方法与您在抽象类中定义的抽象方法不同。记住你需要(由编译器强制)在你的具体类中实现/覆盖那些扩展你的抽象类的abstarct方法。
简单地说,这里是java中的 Overriden方法规则:
答案 1 :(得分:1)
在你的问题中,你混淆了两个方面:在重写方法中使用子类型并在方法参数中使用完全不相关的类型和原语
在上下文方法中,您绝不能将int
从重写方法更改为float
。唯一允许的特殊情况是返回类型协方差。从理论上讲,参数类型可以是逆变的,但这会使方法重载解决方案变得混乱,这已经非常复杂了。
答案 2 :(得分:1)
重写方法应该具有相同数量的方法参数,并且它们的类型应该相同。但他们可以获得协变回报
答案 3 :(得分:0)
以不同的方式说明:返回抽象方法所需的子类型的方法仍然满足合同。虽然采用float的方法不符合该方法采用int的约定。
答案 4 :(得分:0)
协变返回,意味着当一个覆盖一个方法时,被覆盖方法的返回类型被允许是被覆盖方法的返回类型的子类型。 为了用一个例子来澄清这一点,一个常见的例子是Object.clone() - 它被声明为返回一种Object类型。你可以在你自己的班级中覆盖它。