你好 Stackoverflowers,
想象一下下面的基类
import java.util.ArrayList;
public class Array
{
private ArrayList<Object> a = new ArrayList<Object>();
public void add(Object element)
{
a.add(element);
}
public void addAll(Object elements[])
{
for (int i = 0; i < elements.length; ++i)
a.add(elements[i]); // this line is going to be changed
}
}
这是派生类:
public class ArrayCount extends Array
{
private int count = 0;
@Override
public void add(Object element)
{
super.add(element);
++count;
}
@Override
public void addAll(Object elements[])
{
super.addAll(elements);
count += elements.length;
}
}
Array add() 将一个元素添加到本地 ArrayList。 Array addAll() 为每个元素调用本地 ArrayList 添加。
ArrayCount add() 调用其父级的 add(),然后递增计数。 ArrayCount addAll() 调用其父级的 addAll(),然后将计数增加元素数量。
现在进行重大更改。 Base类中注释掉的代码行改为如下:
public void addAll(Object elements[])
{
for (int i = 0; i < elements.length; ++i)
add(elements[i]); // this line was changed
}
现在 ArrayCount addAll() 调用其父级的 addAll(),后者在内部调用已被派生类重写的 add()。
Derived类的作者必须知道Base类是如何实现的。他们必须了解基类中的每一个更改,因为它可能会以不可预测的方式破坏他们的派生类。
我正在寻找一种正确的方法来实现这一点,尊重黑盒编程概念。因为这个例子迫使派生类的编写者知道基类是如何实现的并知道每一个变化
最佳答案
我假设“黑匣子”的意思是:“派生类的实现者必须不知道基类数组的实现细节”。我会选择使用委托(delegate)的装饰器,因为这可能是更好的方法:
public class ArrayCount {
private int count = 0;
private Array a;
public ArrayCount(Array a) {
this.a = a;
}
public void add(Object element) {
a.add(element);
++count;
}
public void addAll(Object elements[]) {
a.addAll(elements);
count += elments.length;
}
}
注意:为了简洁起见,我省略了输入参数检查。
如果Array
和ArrayCount
都实现相同的接口(interface),例如IArray
,您仍然可以互换使用这些类:
interface IArray {
public void add(Object element);
public void addAll(Object elements[]);
}
...
Array implements IArray {...}
ArrayCount implements IArray {...}
关于java - 黑匣子和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38793139/