新手问题在这里。我正在努力教自己,有时单独的路线可能令人沮丧。我在Liang的Java编程简介第8版(练习14.1)中遇到了一个问题,我必须修改GeometricObject类来实现Comparable,然后定义一个静态的“max”方法来找到两个GeometricObjects中较大的一个。然后我必须编写一个测试程序,使用这个max方法找到两个矩形中较大的一个。在本书的前面,作者让我们创建了一个扩展GeometricObject的Rectangle子类。我已经修改了GeometricObject类来实现Comparable,并且我已经创建了max方法。然后我修改了Rectangle子类以实现Comparable。我也写了测试程序。
但Eclipse正在通过我的Rectangle类的声明向我提供Big Red X,并说“使用不同的参数不能多次实现接口Comparable:Comparable和Comparable。”那是我的课堂宣言如下:
public class Rectangle extends GeometricObject implements Comparable<Rectangle> {
我试过完全删除参数:
public class Rectangle extends GeometricObject implements Comparable {
...并且错误消息更改为“Comparable是原始类型。对泛型类型Comparable的引用应该参数化。”另外,在这种情况下它会增加第二个错误:“Rectangle类型必须实现继承的抽象方法Comparable.compareTo(Object)”
当我查看这种声明的例子时,他们似乎总是在声明中使用类名作为Comparable的参数,事实上,这就是书中所说的。那么为什么我说不能这样做呢?
然后关于compareTo()方法的第二个错误呢?当我从声明中删除参数时,为什么只指出它?接下来是Rectangle类的代码(如果需要,我也可以发布GeometricObject超类):
public class Rectangle extends GeometricObject implements Comparable<Rectangle> {
private double width;
private double height;
public Rectangle() {
}
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public Rectangle(double width, double height, String color, boolean filled) {
this.width = width;
this.height = height;
setColor(color);
setFilled(filled);
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2 * (width + height);
}
/** Implement the compareTo method defined in Comparable */
public int compareTo(Rectangle o) {
if (getArea() > ((Rectangle)o).getArea())
return 1;
else if (getArea() < ((Rectangle)o).getArea())
return -1;
else
return 0;
}
}
答案 0 :(得分:0)
由于父类几何对象已经实现了Comparable,因此您无需在基类“Rectangle”中再次实现相同的内容。
您的基类应如下所示
public class Rectangle extends geometricObject {
}
由于geometryObject正在实现Comparable甚至矩形类正在实现Comparable。您只需要覆盖矩形类中的compareTo()方法,即可使用max方法进行比较。
答案 1 :(得分:0)
是的,它有点棘手,可能会令人困惑。
当您声明GeometricObject为Comparable时,意味着每个GeometricObject都可以与另一个GeometricObject进行比较 - 因此您可以对GeometricObject列表进行排序(可能是它的子类实例,因为它可能是抽象的)。 因此,当您在GeometricObject中实现Comparable时,您需要实现此功能:
public int compareTo(GeometricObject o) {}
在这一点上,当使用Rectangle-Rectangle自动派生GeometricObject时,它会导出它的超类compareTo方法。当在Rectangle中实现Comparable时,你需要实现这个函数:
public int compareTo(Rectangle o) {}
似乎没有任何问题,因为它似乎是一个常规的重载,但这里是Java中的catch-Generics它只是编译器的语法糖 - 在运行时所有泛型变为Object所以编译后Rectangle将包含2种方法将是相同的。
所以你只选择了一个,虽然如果我们拿你的用例它可能没问题 - 你只能在超类中实现Comparable并在Rectangle中覆盖它并检查它是否是Rectangle的实例并执行你的特定逻辑或使用super阶级逻辑。