gpt4 book ai didi

java - 扩展 ArrayList - 脆弱基类

转载 作者:行者123 更新时间:2023-12-01 20:20:46 25 4
gpt4 key购买 nike

检查 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() 添加到堆栈,然后我们想使用 clear() 清除堆栈基类 - 即 ArrayList -

Stack a_stack = new Stack();
a_stack.push("1");
a_stack.push("2");
a_stack.clear();
  • 问题是在这里

The code successfully compiles, but since the base class doesn't know anything about the stack pointer, the Stack object is now in an undefined state. The next call to push() puts the new item at index 2 (the stack_pointer's current value), so the stack effectively has three elements on it—the bottom two are garbage.

所以我的问题是,为什么

base class doesn't know anything about the stack pointer

换句话说,堆栈指针的状态被保留在哪里?

来源:Why extends is evil

最佳答案

变量 stack_pointer 是 Stack 类的成员,那么 ArrayList 父类(super class)怎么可能知道它呢?因为它不能也不会调用 clear() 不会对其执行任何操作。

您需要重写 Stack 类中的 clear() 方法。

类似于

@Override
public void clear()
{
super.clear();
stack_pointer = 0;
}

然后,当用户在 Stack 上调用 clear() 时,它将导致指针重置。

此外,您还需要注意,用户可以在 Stack 上调用函数 add()insert() 等,因为它们未被覆盖将调用 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;
}
}

关于java - 扩展 ArrayList - 脆弱基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44792157/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com