可比较错误



此处为新手问题。我试着自学,有时独自一人的路线会让人沮丧。我在梁的《Java编程导论》第8版(练习14.1)一书中遇到了一个问题,我必须修改一个GeometricObject类来实现Comparable,然后定义一个静态的"max"方法来找到两个Geometric对象中较大的一个。然后我必须编写一个测试程序,使用这个max方法来找到两个矩形中较大的一个。在本书之前,作者曾让我们创建一个矩形子类,扩展GeometricObject。我修改了GeometricObject类以实现Comparable,并创建了max方法。然后我修改了Rectangle子类来实现Comparable。我也写了测试程序。

但是Eclipse通过Rectangle类的声明给了我一个巨大的红色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()方法的第二个错误呢?为什么只有当我从声明中删除参数时才指出它?矩形类的代码如下(如果需要,我也可以发布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;
}
}

是的,这有点棘手,可能会令人困惑。

当您将GeometricObject声明为Comparable时,这意味着每个Geometric对象都可以与另一个GeometricObject进行比较,这样您就可以对GeometricObjects的列表进行排序(可能是它的子类实例,因为它可能是抽象的)。因此,当你在GeometricObject中实现Comparable时,你需要实现这个功能:

public int compareTo(GeometricObject o) {}

在这一点上,当用Rectangle扩展GeometricObject时,Rectangle自动派生它的超类compareTo方法。当在矩形中实现Comparable时,您需要实现以下功能:

public int compareTo(Rectangle o) {}

这似乎没有问题,因为它看起来像是一个常规的重载,但这里有一个问题——Java中的泛型只是编译器的语法糖——在运行时,所有泛型都变成了Object,所以编译后矩形将包含两个相同的方法。

所以你只能选择一个,尽管如果我们采用你的用例,它可能是可以的——你可以在超类中只实现Comparable,在Rectangle中覆盖它,并检查它是否是Rectangle的实例,并执行你的特定逻辑或使用超类逻辑。

由于父类几何对象已经在实现Comparable,因此不需要在基类"Rectangle"中再次实现相同的对象。

你的基类应该像这个

public class Rectangle extends geometricObject { }

由于geometricObject正在实现Comparable,所以矩形类也在实现Comparaable。您只需要覆盖矩形类中的compareTo()方法,就可以使用max方法进行比较。

最新更新