简体   繁体   English

用Java中的抽象类扩展ArrayList?

[英]Extending ArrayList with an abstract class in Java?

This is a problem I've been working on for a little while now and I've barely made any progress. 这是我已经研究了一段时间的问题,而且我几乎没有取得任何进展。 I've been running into a lot of problems trying to use an abstract class when extending ArrayList. 在扩展ArrayList时尝试使用抽象类时遇到了很多问题。

My first step was to define three classes, Circle, Rectangle, and Triangle that are all concrete subclasses of an abstract class GeometricObject. 我的第一步是定义三个类,Circle,Rectangle和Triangle,它们都是抽象类GeometricObject的具体子类。 The base class has abstract methods getArea() and getPerimeter() that are overridden in the subclasses by the specific getPerimeter() and getArea() formula for that particular object. 基类具有抽象方法getArea()getPerimeter() ,这些抽象方法在子类中被该特定getPerimeter()的特定getPerimeter()getArea()公式覆盖。 This part is completed and is working as intended. 本部分已完成,并且按预期工作。

The next part is where I'm having trouble. 下一部分是我遇到麻烦的地方。 I'm supposed to define a new class GeoemetricObjectList that extends ArrayList<GeometricObject> . 我应该定义一个扩展ArrayList<GeometricObject>的新类GeoemetricObjectList This class should override the add() , remove() , and clear() methods. 此类应重写add()remove()clear()方法。 This class keeps a totalArea and totalPerimeter variable of the objects on the list. 此类在列表上保留对象的totalArea和totalPerimeter变量。

Right now I've created a, quite frankly, messy if statement list in my GeometricObjectList add() method that I'd like to clean up. 现在,坦率地说,我在我要清除的GeometricObjectList add()方法中创建了一个凌乱的if语句列表。 Here is my code for that class so far: 到目前为止,这是我该课程的代码:

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() {

    }

}

When I simply write totalArea += element.getArea() I get the error "The method getArea() is undefined for the type GeometricObject but in my GeometricObject class I have a public abstract getArea() that is overridden by the getArea() method in each concrete (Triangle, Circle, Rectangle) class. 当我简单地编写totalArea += element.getArea() ,出现错误“对于类型GeometricObject,未定义方法getArea() ,但在我的GeometricObject类中,我有一个公共抽象getArea() ,该方法被getArea()方法覆盖在每个具体的(三角形,圆形,矩形)类中。

My next issue is with the remove() method in GeometricObjectList. 我的下一个问题是GeometricObjectList中的remove()方法。 It looks like this: 看起来像这样:

public boolean remove(GeometricObject element) {

    return super.remove(element);
}

I am getting the error "Name clash: The method remove(GeometricObject) of type GeometricObjectList<GeometricObject> has the same erasure as remove(Object) of type ArrayList but does not override it". 我收到错误“名称冲突:类型为GeometricObjectList<GeometricObject>的方法remove(GeometricObject)具有与ArrayList类型的remove(Object)相同的擦除,但没有覆盖它”。 I never received this error when creating the add() method. 创建add()方法时,我从未收到此错误。

Any help with this is REALLY greatly appreciated. 非常感谢您的任何帮助。 If there's any more info you need ask for it and I'll have it up in a second! 如果有更多信息,您需要索取,我将在一秒钟之内完成!

You really had several different issues - including spelling and hiding, 您确实遇到了几个不同的问题-包括拼写和隐藏,

// 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();
  }
}

Well, let's start with first things first. 好吧,让我们从第一件事开始。

This class declaration isn't doing what you believe it's doing: 该类声明没有执行您认为正在执行的操作:

public class GeometricObjectList<GeometricObject> extends ArrayList<GeometricObject>

Java is treating GeometricObject as a type parameter . Java将GeometricObject作为类型参数 If you want to bound the generic strictly to only instances of a GeometricObject , change that signature to this: 如果要仅将泛型仅绑定到GeometricObject实例,请将该签名更改为此:

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

Then Java will identify the type parameter T to only be instances of GeometricObject and its children. 然后,Java将类型参数T识别为仅是GeometricObject及其子代的实例。

You could also eschew the need for the generic type argument altogether and have your ArrayList tightly bound to GeometricObject without a generic: 您也可以完全避免使用泛型类型参数,并在没有泛型的情况下将ArrayList紧密绑定到GeometricObject

public class GeometricObjectList extends ArrayList<GeometricObject>

Next, the signature of add gets to change. 接下来, add的签名add更改。 Since T is already bound to be an instance of GeometricObject , we don't need to explicitly say that's what we're adding. 由于T已经绑定为GeometricObject的实例,所以我们不必明确地说这就是我们要添加的内容。

public boolean add(T element)

If you elected not to use T , then you would keep your signature the same. 如果您选择不使用T ,那么您将保持签名不变。

In either case, the casts also become redundant and can go away. 无论哪种情况,演员阵容都变得多余并且可以消失。

Finally, your remove method isn't overriding the inherited remove - it needs to match the signature as well. 最后,您的remove方法不会覆盖继承的remove它也需要匹配签名。

public boolean remove(Object element)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM