检查Java中的最佳实践,我们发现避免继承是一个很好的实践。其中一个原因可能在以下问题中说明:
这里我们有一个子类" Stack"扩展" ArrayList"
class Stack extends ArrayList
{ private int stack_pointer = 0;
public void push( Object article )
{ add( stack_pointer++, article );
}
public Object pop()
{ return remove( --stack_pointer );
}
public void push_many( Object[] articles )
{ for( int i = 0; i < articles.length; ++i )
push( articles[i] );
}
}
让我们说我们要使用前面代码中定义的push()
添加到堆栈中,然后我们想要使用基类-ie ArrayList的clear()
清除堆栈 -
Stack a_stack = new Stack();
a_stack.push("1");
a_stack.push("2");
a_stack.clear();
代码成功编译,但由于基类不知道 关于堆栈指针的任何事情,Stack对象现在都在 未定义的状态。下一次调用push()会将新项目放在索引2处 (stack_pointer&#39;当前值),因此堆栈有效 它上面有三个元素 - 底部两个是垃圾。
所以我的问题是,为什么
基类对堆栈指针
一无所知
换句话说,堆栈指针的状态在哪里被保留?
答案 0 :(得分:3)
变量stack_pointer
是Stack
类的成员,那么ArrayList
超类怎么能对它有所了解呢?因为它不能也不会调用clear()
不会对它做任何事情。
您需要覆盖clear()
课程中的Stack
方法。
像
这样的东西@Override
public void clear()
{
super.clear();
stack_pointer = 0;
}
然后当用户在clear()
上调用Stack
时,它将导致指针重置。
此外,您需要注意,用户可以调用add()
上的insert()
,Stack
等函数,因为它们未被覆盖,因此会调用ArrayList
功能。这可能不是你想要的。
更好的方法是在内部创建一个Stack
ArrayList
,这样您就可以隐藏需要隐藏的方法。
像
这样的东西public class Stack
{
private ArrayList<Object> stack = new ArrayList<Object>();
private int stack_pointer;
public void push(Object obj)
{
stack.add(stack_pointer++, obj);
}
// Other methods
public void clear()
{
stack.clear();
stack_pointer = 0;
}
}
答案 1 :(得分:0)
以下是其中一种方式:
import java.util.ArrayList;
class Stack extends ArrayList {
private int stack_pointer = 0;
private int stack_mem = 16;
private ArrayList<Object> mem = new ArrayList<Object>();
public void push(Object article) {
if (stack_pointer < stack_mem) {
mem.add(article);
stack_pointer++;
}
}
public Object pop() {
if (stack_pointer > 0) {
return mem.remove(stack_pointer--);
}
return null;
}
public void clear() {
stack_pointer = 0;
mem.clear();
}
}