代码之家  ›  专栏  ›  技术社区  ›  eomeroff

从向量继承Java类堆栈的消极方面是什么?

  •  17
  • eomeroff  · 技术社区  · 15 年前

    通过扩展类向量,Java设计人员能够快速创建类堆栈。是什么 继承使用的负面方面,特别是对于类堆栈?

    谢谢。

    6 回复  |  直到 13 年前
        1
  •  22
  •   Uri    15 年前

    一个问题是堆栈是类,而不是接口。这与集合框架的设计不同,集合框架中的名词通常表示为接口(例如,列表、树、集合等),并且有特定的实现(例如,ArrayList、LinkedList)。如果Java可以避免向后兼容性,那么一个更合适的设计是有一个堆栈接口,然后是VectorStack作为一个实现。

    第二个问题是堆栈现在绑定到向量,这通常是避免的,有利于数组列表等。

    第三个问题是,您不能轻松地提供自己的堆栈实现,并且这些堆栈支持非常非堆栈的操作,例如从特定索引获取元素,包括索引异常的可能性。作为一个用户,您可能还必须知道堆栈的顶部是在索引0还是在索引N。该接口还公开了实现细节,如容量。

    在原始Java类库中的所有决策中,我认为这是比较奇怪的一种。我怀疑聚合比继承要贵得多。

        2
  •  25
  •   polygenelubricants    15 年前

    有效Java第二版,第16项:继承优于继承 :

    只有在子类确实是 亚型 超类的。换句话说,一个类 只应扩展类 只有当两个类之间存在“is-a”关系时。如果你想去上课 扩展班级 ,问你自己这个问题:是每 真的 ?如果你不能如实回答“是”这个问题, 不应延长 . 如果答案是否定的,通常情况下 应包含的私有实例 并公开一个更小更简单的API; 不是 只是它实现的一个细节。

    在Java平台库中有许多明显违反此原则的情况。例如,堆栈不是向量,因此 Stack 不应延长 Vector . 同样,属性列表不是哈希表,因此 Properties 不应延长 Hashtable . 在这两种情况下,最好使用合成物。

    这本书更加详细,并与 第十七条继承或者禁止继承的设计和文件 ,建议不要在设计中过度使用和滥用继承。

    下面是一个简单的例子,展示了 允许联合国 类行为:

        Stack<String> stack = new Stack<String>();
        stack.push("1");
        stack.push("2");
        stack.push("3");
        stack.insertElementAt("squeeze me in!", 1);
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
        // prints "3", "2", "squeeze me in!", "1"
    

    这严重违反了堆栈抽象数据类型。

    也见

        3
  •  6
  •   John Topley    15 年前

    Stack 子类 Vector 显示不适合堆栈的方法,因为堆栈不是向量(它违反了 Liskov Substitution Principle )

    例如,堆栈是一个后进先出的数据结构,但是使用这个实现,您可以调用 elementAt get 方法在指定索引处检索元素。或者你可以使用 insertElementAt 破坏堆栈合同。

    我认为乔舒亚·布洛克公开说 子类 矢量 是个错误,但不幸的是我找不到参考资料。

        4
  •  3
  •   jjnguy Julien Chastang    15 年前

    好, Stack 应该是一个接口。

    这个 接口应该定义堆栈可以执行的操作。然后可能会有不同的 在不同情况下表现不同。

    但是,因为 是一个具体的类,这不可能发生。我们仅限于堆栈的一个实现。

        5
  •  2
  •   M. Jessup    15 年前

    除了上面提到的主要有效点之外,从向量继承堆栈的另一个大问题是向量是完全同步的,所以无论您是否需要它,您都会得到这种开销(参见StringBuffer和StringBuilder)。就我个人而言,每当我想要一堆的时候,我都倾向于使用arraydeque。

        6
  •  1
  •   Graphics Noob    15 年前

    它违反了我们都学到的关于继承的第一条规则:你能用一个直的脸说一个堆栈是一个向量吗?显然不是。

    另一个更合乎逻辑的操作是使用聚合,但最佳选择IMO将是堆栈的接口,可以通过任何适当的数据结构来实现,与C++ STL所做的类似(但不完全相同)。

    推荐文章