使用Java中的抽象类扩展ArrayList?

时间:2014-04-23 05:02:44

标签: java arraylist abstract-class

这是一个我现在已经工作了一段时间的问题,而且我几乎没有取得任何进展。在扩展ArrayList时,我一直在尝试使用抽象类时遇到很多问题。

我的第一步是定义三个类,Circle,Rectangle和Triangle,它们都是抽象类GeometricObject的具体子类。基类具有抽象方法getArea()getPerimeter(),这些方法在子类中由特定对象的特定getPerimeter()getArea()公式覆盖。这部分已经完成,正在按预期工作。

下一部分是我遇到麻烦的地方。我应该定义一个扩展GeoemetricObjectList的新类ArrayList<GeometricObject>。此类应覆盖add()remove()clear()方法。该类保留列表中对象的totalArea和totalPerimeter变量。

现在我已经在GeometricObjectList add()方法中创建了一个非常坦率的,混乱的if语句列表,我想清理它。到目前为止,这是我的代码:

import java.util.ArrayList;

@SuppressWarnings("hiding")
public class GeometricObjectList<GeometricObject> extends ArrayList<GeometricObject>{

    final static long serialVersionUID = 1L;

    public double totalArea = 0;
    public double totalPerimeter = 0;


    public boolean add(GeometricObject element){
        if(element instanceof Rectangle) {
            totalArea += ((Rectangle)element).getArea();
            totalPerimeter += ((Rectangle)element).getPerimeter();
        }
        if(element instanceof Circle) {
            totalArea += ((Circle)element).getArea();
            totalPerimeter += ((Circle)element).getArea();
        }
        if(element instanceof Triangle) {
            totalArea += ((Triangle)element).getArea();
            totalPerimeter +=((Triangle)element).getArea();
        }

        return super.add(element);
    }

    public boolean remove(GoemetricObject element) {

        return super.remove(element);
    }

    public void clear() {

    }

}

当我简单地写totalArea += element.getArea()时,我得到了错误&#34;对于GeometricObject类型,方法getArea()是未定义的,但在我的GeometricObject类中,我有一个公共抽象getArea(),它是在每个具体(三角形,圆形,矩形)类中被getArea()方法覆盖。

我的下一个问题是使用GeometricObjectList中的remove()方法。它看起来像这样:

public boolean remove(GeometricObject element) {

    return super.remove(element);
}

我收到错误&#34;名称冲突:类型GeometricObjectList<GeometricObject>的remove(GeometricObject)方法与ArrayList类型的remove(Object)具有相同的删除功能,但不会覆盖它#34;。创建add()方法时,我从未收到此错误。

对此的任何帮助真的非常感谢。如果还有其他信息需要请求,我会在一秒钟内完成!

2 个答案:

答案 0 :(得分:2)

你真的有几个不同的问题 - 包括拼写和隐藏,

// Make sure you have these methods in your GeometricObject.
// private static abstract class GeometricObject {
//  public abstract double getArea();
//  public abstract double getPerimiter();
// }

// Do not use that annotation. It was warning you!
public class GeometricObjectList extends
    ArrayList<GeometricObject> {

  final static long serialVersionUID = 1L;

  public double totalArea = 0;
  public double totalPerimeter = 0;

  public boolean add(GeometricObject element) {
    if (element != null && super.add(element)) {
      totalArea += element.getArea(); // add area
      totalPerimeter += element.getPerimiter(); // add perimeter
      return true;
    }
    return false;
  }

  public boolean remove(GeometricObject element) { // Spelling!
    if (element != null && super.remove(element)) {
      totalArea -= element.getArea(); // subtract area
      totalPerimeter -= element.getPerimiter(); // subtract perimeter
      return true;
    }
    return false;
  }

  public void clear() {
    super.clear();
  }
}

答案 1 :(得分:2)

好吧,让我们先从第一件事开始。

这个类声明没有做你认为它正在做的事情:

public class GeometricObjectList<GeometricObject> extends ArrayList<GeometricObject>

Java正在将GeometricObject视为类型参数。如果要将通用严格限制为仅GeometricObject的实例,请将该签名更改为:

public class GeometricObjectList<T extends GeometricObject> extends ArrayList<T>

然后,Java会将类型参数T标识为GeometricObject及其子项的实例。

您也可以完全避免使用泛型类型参数,并使ArrayListGeometricObject紧密绑定,而不是通用:

public class GeometricObjectList extends ArrayList<GeometricObject>

接下来,add的签名会发生变化。由于T已被绑定为GeometricObject的实例,因此我们无需明确说明我们正在添加的内容。

public boolean add(T element)

如果您选择不使用T,那么您的签名将保持不变。

在任何一种情况下,演员阵容也会变得多余,可能会消失。

最后,您的remove方法不会覆盖继承的remove - 它也需要匹配签名。

public boolean remove(Object element)