java继承与组合(实现堆栈)

时间:2009-09-13 23:32:29

标签: java inheritance list stack composition

我正在尝试在java中实现一个Stack(使用list interface:Interface List)。

我想以两种不同的方式实现它:使用组合和继承。

对于继承,到目前为止我有:

 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;

 public class StackInheritance implements List {
      //implement list methods
 }

对于作文,我有:

 import java.util.List;

 public abstract class StackComposition implements List {
     // implement some standard methods
 }

 public class StackViaList extends StackComposition {
     // implement methods that have not been implemented in the abstract
     // class
 }

我很困惑从哪里开始。我之前从未使用过接口,所以我是否应该使用List方法来“模仿”堆栈,例如使用Array或ArrayList?

另外,对于合成,我不明白应该在StackComposition中使用哪些方法以及应该在StackViaList中使用什么方法。在不完全理解接口以及继承和组合之间,我有点迷失。我似乎还不能“得到它”......

任何帮助将不胜感激,谢谢!

5 个答案:

答案 0 :(得分:9)

对于组合,堆栈类应该有一个列表,而不是实现或扩展基于List的类。继承是一种“IS A”关系,而组合是“HAS A”关系。

例如:

public class StackWithComposition
{
    // StackWithComposition HAS A List (rather than IS A List)
    private List myList = new ArrayList();

    public void push(object item)
    {
        // add item to myList, etc.
    }

    public object pop()
    {
        // return item at top (or end) of myList
    }

    // etc.
}

请注意,您可能希望将其设为泛型类,而不是处理原始对象,但这可能就是这个想法。

在这种情况下,基于组合的解决方案可能优于基于继承的解决方案。当你从类/接口继承时,你应该问自己,Stack是List吗?大多数Stacks不应该为用户提供对所有原始List方法的访问权限,因此最好隐藏您正在使用List作为内部数据结构的面。使用组合列表可以完全隐藏您使用List作为内部结构的事实。

答案 1 :(得分:2)

我认为这不是一个真正的问题。这是“你可以为我做功课”的问题。

更有意义的问题是:

  • 继承和组合有什么区别?
  • 每个实现堆栈的优点/缺点是什么?
  • 什么是堆栈?
安迪给了这三个人很好的答案。

不幸的是,看起来原始海报的老师自己并不了解这些概念,因为这项任务是荒谬的。实现java.util.List的类不是堆栈,或者更确切地说,它作为堆栈使用是不安全的,因为它要求非堆栈安全操作是公共的。堆栈是一个比列表更具限制性的接口。

难怪原始海报很混乱。

答案 2 :(得分:1)

你的概念是颠倒的。

继承,正如所说的那样,当您从现有对象“获取”该功能时。这被称为IS-A关系。例如,卡车 IS-A 车辆。

在你的第一个不是继承的样本中,因为你没有从列表中取任何东西。在您的示例中,您正在“实施”该列表而不是“扩展”它。

组合是指使用其他人构建对象(您正在组合对象)。这被称为HAS-A关系。例如卡车 HAS-A 车轮(但不是车轮)。在您的示例中,您正在“扩展”(继承)其他对象

最后,OOP中的接口是一个提交履行对象的“合同”。对象将响应哪些函数或消息。

在Java中,“interface”也是一个工件,其中定义了对象将响应的方法。

因此,对于堆栈,您必须定义Stack具有的方法(接口)

public interface Stack {
     public void push( Object o );
     public Object pop();
}

然后使用继承,您可以创建堆栈实现。为此,您必须从其他类扩展(或继承)功能。我们说ArrayList

 /**
  * Sample stack implementation using inheritance
  */
public class ArrayListStack extends ArrayList implements Stack {
// you use the keyword extends because you're inheriting from ArrayList
// and the keyword implements because you claim to respond to push and pop methods.

     public void push( Object o ) {
          this.add( o ); // add inherited from ArrayList
     }
     public Object pop() {
         return this.remove( this.size() -1 ); // remove inherited from ArrayList
     }
}

由于你是从ArrayList“继承”的,所以你需要的大多数都已存在。但是,这是否代表IS-A关系? Stack IS-An ArrayList总是这样吗?

要使用合成来实现堆栈,您必须将对象与另一个对象“合并”。

  /**
   * Sample stack implementation using composition
   */ 
 public class ComposedStack  implements Stack {
      // you didn't extend anything here

      // But you'll need another object to help you 
      // to do the work.
      private ArrayList holder = .... // Should be declared as List holder = ....


    public void push( Object o ) {
         this.holder.add( o );
    }

    public Object pop() {
        return this.holder.remove( this.holder.size() -1 );
    }
 }

实现非常相似,您正在使用ArrayList

中的“add”和“remove”方法

区别在于第一种使用继承的情况,您不仅使用这两种方法,而且还将对象完全耦合到ArrayList本身(因为您还继承了所有其他方法) ,以及ArrayList的属性)

当你使用组合时,你不会将你的对象耦合到arraylist(或耦合很低,这是一件好事)你只是使用另一个对象来帮助你做工作。在这种情况下,它是一个ArrayList。

从外部(使用组合),你没有看到里面有一个ArrayList,这是信息隐藏。你班级的用户(客户)只能看到两种可用的“推”和“弹出”方法,而且你的课程没有其他任何可用的方法。它看起来像一个“真正的”堆栈。

使用继承(使用extends关键字),类的客户端也会看到来自ArrayList的所有方法,尽管您可能只希望使用pop和push,但是没有什么能阻止客户端使用“removeRange”实例。

结论:理解is-a和has-a之间的差异对于OO技术至关重要。我希望这能帮到你。

答案 3 :(得分:0)

class stack
{

    int n,item,top;
    public stack()
    {
        n=7;
        top=-1;
    }}
    class student extends stack
    {
    int [] stk=new int[4];
    public void insert(int a)
    {
        if(top>=n-1)
        System.out.println("over flow");
        else
        {
            top++;
            stk[top]=a;
        }   
    }
        public void deletestk()
    {
        if(top<0)
            System.out.println("under flow");
            else
            {
                item=stk[top];
                top--;
                    System.out.println("deleted item are"+item);
            }
    }
        public void destroy()
    {
        if(top<0)
            System.out.println("under flow");
            else
            {

            top=-1;
    }
    }
    public void view()
    {
        int i;
        i=top;
        while(i>=0)
        {
                System.out.println(stk[i]);
                i--;
        }
    }   

    }
    class stackfloat extends stack
    {

        float [] stk=new float[6];
    }
    class stkstring extends stack
    {
        String [] stk=new String[5];
    }
    class stackmain
{
    public static void main(String arg[])
    {
        stack ob=new stack();
        student obj=new student();
            obj.deletestk();
        obj.insert(5);
            obj.insert(6);
                obj.insert(64);
                    obj.insert(45);
                        obj.insert(3);
                        obj.view();
                        obj.deletestk();
                        obj.view();
                        obj.destroy();
                        obj.view();



    }
}

答案 4 :(得分:-1)

java的组合是实现has-a关系的设计技术