Java - 如何继承泛型ArrayList以使得MyArrayList<foo>的实例成为ArrayList<foo>的子类?

10
我希望保持我的子类通用性,并且所有我想要改变的只是 ArrayList 的 add(Object) 方法,使其在调用 arrayList.add(null) 时不添加任何内容(ArrayList 的正常实现会添加 null,但我希望它什么也不做)。

2
思想警察正在这个问题上到处游荡。楼主的要求已经清楚地说明了,我不认为有任何理由不能按照所要求的回答这个问题。@fbafelip已经展示了如何做到这一点。提到的委托替代方案需要更多数量级的代码。 - user207421
4
可以使用多种方法向ArrayList<T>(或任何List<T>)添加元素:add(T)add(int,T)addAll(Collection<T>)addAll(int,Collection<T>),通过构造函数以及通过Iterator<T>ListIterator<T>add方法,并且可以通过以任何一种方式修改使用subList返回的视图来添加元素。您需要处理所有这些吗? - trutheality
思想警察?你真的要把我的答案和极权主义国家相比较吗?因为我所使用的只是一个权威论证……好的,明白了。 - Amir Afghani
@AmirAfghani - 哈哈,我想他的意思是你的回答有一些读心术的成分,而不是它具有奥威尔式的性质*保持中立* - Paul Bellora
1
@truthreality 这仍然是有一定工作量的,而且作为新代码也需要进行测试。 - user207421
显示剩余4条评论
4个回答

14
在这种情况下,你确实应该优先选择组合而不是继承,因为如果你忘记覆盖ArrayList中添加/更改元素的一个方法(例如,你可能会忘记覆盖set方法),仍然有可能有空元素。
但是,既然问题是如何对ArrayList进行子类化,那么以下是你可以做到的:
import java.util.ArrayList;

public class MyArrayList<T> extends ArrayList<T> {
    public boolean add(T element) {
        if (element != null) return super.add(element);
        return false;
    }
}

如果您可以保证这是唯一修改数组列表行为的地方,那么这个解决方案是合理的,因为这样外部就不会察觉到这个实现细节。 - Jeremy
为什么你不喜欢我的修改版本?它的行为完全相同,但代码更好(有几个原因)。 - Bohemian
1
@Bohemian 我只是想让它更明确,因为这是一个示例代码。 - fbafelipe

10

这是一个例子,您应该优先选择组合而不是继承。

与其扩展ArrayList,您应该创建一个类,该类具有一个ArrayList成员字段并公开一个add方法来处理正确的操作。

阅读Effective Java。 这里是描述此问题的示例


2
我同意他应该优先选择组合而不是继承,但也许他会将ArrayList传递给外部库,所以在那种情况下组合就行不通了。他询问如何对其进行子类化,而不是是否应该这样做。 - fbafelipe
1
你的引用和示例不适用。OP 明确希望超类的行为。 - user207421
2
这真的没有帮助到提问者。他接下来的问题将是:> 如何对通用列表进行子类化,以便MyList <foo>的实例将成为List <foo>的子类? - xehpuk
5
我认为Amir引用的内容确实适用。是的,原帖的目标明确。而且,Amir没有回答所问的问题。然而,他提出了一个可能是原帖作者没有想到的好点子。虽然没有直接说明,但很明显,原帖作者的最终目标是在他的列表中没有'null'值。直接回答他的问题可能会或可能不会给他那种行为,这取决于'ArrayList'的实现方法。提供一个阐述潜在问题的答案而不是直接回答并没有什么问题。 - Tim Pote
@fbafelipe OP没有描述他的用例,但假设你是正确的,他想将ArrayList传递给外部库。为什么这种方法是禁止的?你可以简单地在列表本身上公开一个getter。 - Amir Afghani
显示剩余6条评论

0

想限制List中的内容是完全值得尊重的,但是默默地忽略参数是有问题的。不过,这就是为什么我们有Apache Commons Collections。可能还有Guava等效工具。使用它们之一来声明ArrayListfinal子类,这样就没有人可以破坏您的意图。


0

你有没有考虑实现一个过滤器,在调用add方法时进行过滤?如果它只在代码中的一个地方被调用,那么这可能是最简单的方法。一个简单的if语句可能会起作用。

if (input/object != null) { 
    arrayList.add(input/object);
} 
else { 
    //do something else instead, or nothing
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接