实现基类方法的java方法是否可以返回继承的类



假设我有一个标准的Draw类,它继承了Circle和Square类。有没有办法做到以下几点?也许是仿制药?

class Draw {
  public abstract Draw duplicate();
}
class Circle extends Draw {
  public Circle duplicate() {
    return new Circle();
  }
}
class Square extends Draw {
  public Square duplicate() {
    return new Square();
  }
}

是的,可以让重写方法返回一个类型,该类型是超类方法返回类型的子类。这种被称为"协变返回类型"的技术在Java返回类型教程的底部进行了描述。这是因为CircleSquareDraw,所以即使你有一个超类引用,并且你不知道或不在乎你真正有哪个子类,你仍然可以保证得到一个Draw

顺便说一句,要编译代码,只需要使Draw类成为abstract。其他一切,包括协变返回类型,看起来都很好。

是的,从Java 5开始就可以了。

由于Java 5,子类中的方法可能会返回一个对象,该对象的类型是该方法在超类中使用相同签名返回的类型的子类。(来源)。这被称为协变返回类型。

我会在这里使用泛型:

class Draw<T> {
  public abstract T duplicate();
}
class Circle extends Draw<Circle> {
  @Override
  public Circle duplicate() {
    return new Circle();
  }
}
class Square extends Draw<Square> {
  @Override
  public Square duplicate() {
    return new Square();
  }
}

我认为您想要做的是:

public abstract class Draw<T extends Draw> {
    public abstract T duplicate();
}
public class Circle extends Draw<Circle> {
    @Override
    public Circle duplicate() {
        return new Circle();
    }
}
public class Square extends Draw<Square> {
    @Override
    public Square duplicate() {
        return new Square();
    }
}
  1. 泛型的使用(对T有约束,应该扩展Draw,以避免像Circle extends Draw<List>这样的奇怪继承)
  2. abstract关键字添加到Draw

然后,您可以执行以下操作:

Square originalSquare = new Square();
Circle originalCircle = new Circle();
Square duplicatedSquare = originalSquare.duplicate();
Circle duplicatedCircle = originalCircle.duplicate();

编辑

如果没有泛型,你可以做这样的事情:

public abstract class Draw {
    public abstract Draw duplicate();
}
public class Circle extends Draw {
    @Override
    public Circle duplicate() {
        return new Circle();
    }
}
public class Square extends Draw {
    @Override
    public Square duplicate() {
        return new Square();
    }
}

多亏了Pavel、rgettman和Enno Shioji,我才不知道"协变返回类型"。

最新更新