2009-09-13 6 views
3

J'essaye d'implémenter une pile en Java (en utilisant l'interface de la liste: Interface List).héritage java en fonction de la composition (implémentation d'une pile)

Je veux l'implémenter de deux manières différentes: en utilisant la composition et l'héritage.

Pour l'héritage, jusqu'à présent je:

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

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

Pour la composition, j'ai:

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 
} 

Je suis confus quant à l'endroit où aller d'ici. Je n'ai jamais utilisé d'interface auparavant, je suis donc supposé utiliser les méthodes List pour "imiter" une pile, en utilisant un Array ou un ArrayList par exemple?

Aussi, pour la composition, je ne comprends pas quelles méthodes devraient aller dans StackComposition et ce qui devrait aller dans StackViaList. Entre ne pas bien comprendre les interfaces ainsi que l'héritage et la composition, je suis un peu perdu. Je ne peux pas sembler juste "obtenir" encore ...

Toute aide serait appréciée, merci!

+3

Les devoirs, n'est-ce pas? – cletus

Répondre

9

Pour la composition, la classe de pile doit avoir une liste, ne pas implémenter ou étendre une classe basée sur la liste. L'héritage est une relation "IS A", tandis que la composition est une relation "HAS A".

Par exemple:

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. 
} 

Notez que vous voudrez probablement faire une classe générique, plutôt que de traiter des objets bruts, mais ce serait l'idée.

Dans ce cas, la solution à base de composition est probablement préférable à la solution basée sur l'héritage. Lorsque vous héritez d'une classe/interface, vous devriez vous demander, est-ce que Stack est une liste? La plupart des piles ne doivent pas permettre à l'utilisateur d'accéder à toutes les méthodes de liste brutes, il est donc préférable de masquer le visage que vous utilisez comme liste de données interne. L'utilisation d'une liste composée vous permet de masquer complètement le fait que vous utilisez une liste comme structure interne.

+0

Andy- Merci pour votre aide. Je comprends ce que tu veux dire maintenant. J'ai implémenté la pile avec l'héritage et la composition. Je vois toutes les méthodes de List brutes que je dois inclure avec l'héritage, ce qui, pour les besoins de la pile, n'a aucun sens. Merci :) – littleK

2

Je ne pense pas que ce soit une vraie question. Ceci est une question "pouvez-vous faire mon devoir pour moi".

Plus significatives questions seraient:

  • Quelle est la différence entre l'héritage et la composition?
  • Quels sont les avantages/inconvénients de l'implémentation d'une pile avec chacun?
  • Qu'est-ce qu'une pile?

Andy a donné de bonnes réponses aux trois.

Malheureusement, il semble que l'enseignant de l'affiche originale ne comprenne pas très bien les concepts lui-même, puisque l'affectation est absurde. Une classe qui implémente une java.util.List n'est pas une pile, ou plutôt, elle n'est pas sûre à utiliser en tant que pile, car elle nécessite que les opérations non-stack-safe soient publiques. Une pile une interface plutôt plus restrictive qu'une liste.

Pas étonnant que l'affiche originale soit confuse.

1

Vous avez les concepts à l'envers.

Héritage, comme le dit le mot lorsque vous "prenez" à partir d'un objet existant la fonctionnalité. Ceci est connu comme relation IS-A. Par exemple un camion IS-A Véhicule.

Dans votre premier exemple, ce n'est pas un héritage, car vous ne prenez rien dans la liste. Dans votre exemple, vous "mettez en œuvre" cette liste sans "l'étendre".

La composition consiste à créer un objet en utilisant d'autres objets (vous combinez des objets). Ceci est connu comme relation HAS-A. Par exemple une roue de camion HAS-A (mais n'est pas une roue). Dans votre exemple vous "étendez" (héritant) d'un autre objet

Enfin interface dans OOP est le "contrat" ​​un objet est engagé à remplir. Quelles fonctions ou messages un objet répondra.

En Java, "interface" est également un artefact où les méthodes auxquelles un objet va répondre sont définies.

Donc, pour une pile vous devez définir les méthodes d'une pile a (l'interface)

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

Ensuite, en utilisant l'héritage vous pouvez créer la mise en œuvre de la pile. Pour ce faire, vous devrez étendre (ou hériter) des fonctionnalités d'autres classes. Disons que 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 
    } 
} 

Puisque vous êtes « héritant » de ArrayList, plus le que vous avez besoin est déjà là. Mais est-ce que cela représente un relatioship IS-A? Est-il vrai que Stack IS-An ArrayList est toujours?

Pour implémenter la pile en utilisant composition vous devez "combiner" votre objet avec un autre.

/** 
    * 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); 
    } 
} 

La mise en œuvre est très similaire, vous utilisez « ajouter » et « supprimer » les méthodes de la ArrayList

La différence est dans le premier cas en utilisant l'héritage vous n'êtes pas seulement l'utilisation de ces deux méthodes, mais vous COUPling votre objet complètement à l'ArrayList lui-même (parce que vous avez aussi hériter toutes les autres méthodes, et attribuer la ArrayList a)

Lorsque vous utilisez la composition , vous ne couplent pas votre objet l'arrayl ist (ou le couplage est faible, ce qui est une bonne chose) Vous utilisez simplement un autre objet pour vous aider à faire le travail. Dans ce cas, c'était une ArrayList. De l'extérieur (en utilisant la composition), vous ne voyez pas de ArrayList à l'intérieur, c'est une information qui se cache. L'utilisateur (le client) de votre classe ne voit que deux méthodes disponibles "push" et "pop" et il n'y a rien de plus à faire avec votre classe. Cela ressemble à une "vraie" pile.Avec l'héritage (utilisant le mot-clé extends), le client de la classe voit aussi toutes les méthodes de ArrayList bien que vous souhaitiez que seules les commandes pop et push soient utilisées, rien n'empêche le client d'utiliser "removeRange" par exemple.

Conclusion: Comprendre les différences entre les relations is-a et has-a est essentiel pour la technologie OO. J'espère que cela t'aidera.

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(); 



    } 
} 
Questions connexes