Java 默认方法的协变返回类型
我可以用协变返回类型重写方法,但是否可以用协变返回类型重写默认值方法?在下面的示例中,我希望在不重写默认方法的情况下重写getFirstLeg,但Java不允许这样做。我也不想让Animal成为一个通用接口,因为可能有很多参数,Animal在很多地方都被使用Java 默认方法的协变返回类型,java,default-method,covariant-return-types,Java,Default Method,Covariant Return Types,我可以用协变返回类型重写方法,但是否可以用协变返回类型重写默认值方法?在下面的示例中,我希望在不重写默认方法的情况下重写getFirstLeg,但Java不允许这样做。我也不想让Animal成为一个通用接口,因为可能有很多参数,Animal在很多地方都被使用 interface Leg { } interface Animal { List<? extends Leg> getLegs(); default Leg getFirstLeg() {
interface Leg {
}
interface Animal {
List<? extends Leg> getLegs();
default Leg getFirstLeg() {
return getLegs().get(0);
}
}
abstract class AnimalImpl<T extends Leg> implements Animal {
private List<T> legs;
@Override
public List<T> getLegs() {
return legs;
}
}
interface DuckLeg extends Leg {
}
interface Duck extends Animal {
@Override
List<? extends DuckLeg> getLegs(); //covariant return type
@Override
DuckLeg getFirstLeg(); //I do not want to rewrite this method
}
class DuckImpl extends AnimalImpl<DuckLeg> implements Duck {
//Error: java: DuckImpl is not abstract and does not override abstract method getFirstLeg() in Duck
}
接口腿{
}
界面动物{
List是的,Java确实有继承方法的协变返回类型。但这里的问题不是getFirstLeg
是一个默认的方法,而是Java的泛型不是协变的;它们是不变的。也就是说,List
不是一个列表如果你想要协变,请键入Leg
。你可以这样做删除大部分代码
这包括:
interface Leg {
}
interface Animal<T extends Leg> {
List<T> getLegs();
default T getFirstLeg() {
return getLegs().get(0);
}
}
abstract class AnimalImpl<T extends Leg> implements Animal<T> {
private List<T> legs;
@Override
public List<T> getLegs() {
return legs;
}
}
interface DuckLeg extends Leg {
}
interface Duck extends Animal<DuckLeg> {
}
class DuckImpl extends AnimalImpl<DuckLeg> implements Duck {
// no errors
}
接口腿{
}
界面动物{
列出getLegs();
默认的getFirstLeg(){
返回getLegs().get(0);
}
}
抽象类AnimalImpl实现了Animal{
私人名单;
@凌驾
公共列表getLegs(){
返回支腿;
}
}
接口鸭腿延伸腿{
}
鸭与动物的接口{
}
类DuckImpl扩展AnimalImpl实现Duck{
//没有错误
}
请看我文章的最后一句话。我担心让动物(或任何其他广泛使用的界面)成为通用的,因为如果我们想更改参数,我们必须更改很多地方。请看我文章的最后一句话。我担心让动物(或任何其他广泛使用的界面)成为通用的泛型,因为如果我们想更改一个参数,我们将不得不更改很多位置。虽然列表不是一个列表制作Animal
generic,但我看到的唯一解决问题的方法正是因为Java泛型是不变的。此外,列表如果是这样,为什么我可以使用列表
interface Animal<T extends Leg> {
List<T> getLegs();
default T getFirstLeg() {
return getLegs().get(0);
}
}
interface Duck extends Animal<DuckLeg> {
// able to remove the override of getLegs
//@Override
//List<DuckLeg> getLegs(); //covariant return type
// able to remove the override of getFirstLeg
//@Override
//DuckLeg getFirstLeg(); //I do not want to rewrite this method
}
class DuckImpl extends AnimalImpl<DuckLeg> implements Animal<DuckLeg> {
}
interface Leg {
}
interface Animal<T extends Leg> {
List<T> getLegs();
default T getFirstLeg() {
return getLegs().get(0);
}
}
abstract class AnimalImpl<T extends Leg> implements Animal<T> {
private List<T> legs;
@Override
public List<T> getLegs() {
return legs;
}
}
interface DuckLeg extends Leg {
}
interface Duck extends Animal<DuckLeg> {
}
class DuckImpl extends AnimalImpl<DuckLeg> implements Duck {
// no errors
}