假设我有一个标准的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返回类型教程的底部进行了描述。这是因为Circle
和Square
是Draw
,所以即使你有一个超类引用,并且你不知道或不在乎你真正有哪个子类,你仍然可以保证得到一个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();
}
}
- 泛型的使用(对
T
有约束,应该扩展Draw
,以避免像Circle extends Draw<List>
这样的奇怪继承) - 将
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,我才不知道"协变返回类型"。