假设我有标准的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();
}
}
答案 0 :(得分:4)
是的,你可以从Java 5开始。
从Java 5开始,子类中的方法可能返回一个对象,该对象的类型是由超类中具有相同签名的方法返回的类型的子类。 (source)。这称为协变返回类型。
答案 1 :(得分:4)
是的,可以让重写方法返回一个类型,该类型是超类方法的返回类型的子类。称为“协变返回类型”的这种技术被描述为at the bottom of a Java tutorial on return types。这是因为Circle
和Square
是Draw
s,所以即使你有一个超类引用,并且你不知道或不关心你真正拥有哪个子类,你仍然是保证可以取回Draw
。
顺便说一句,要让您的代码进行编译,您只需要创建Draw
类abstract
。其他所有内容,包括协变返回类型,看起来都不错。
答案 2 :(得分:1)
我会在这里使用泛型:
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();
}
}
答案 3 :(得分:1)
我认为您想要做的是以下内容:
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,我不知道“协变返回类型”。