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.
Les devoirs, n'est-ce pas? – cletus