Sont la Composition et l'Héritage de la même manière? Si je veux mettre en œuvre la composition de modèles, comment puis-je le faire en Java?
Réponses
Trop de publicités?Ils sont absolument différentes. L'héritage est un "est-un" de la relation. La Composition est une "a-un".
Vous n'composition de disposer d'une instance d'une autre classe C
comme un champ de votre classe, au lieu de l'étendre C
. Un bon exemple de cas où la composition aurait été beaucoup mieux que l'héritage est - java.util.Stack
, qui s'étend actuellement java.util.Vector
. Ce qui est maintenant considéré comme une faute. Une pile "est-PAS-un" vecteur; vous ne devriez pas être autorisé à insérer et supprimer des éléments de manière arbitraire. Il aurait été de la composition à la place.
Malheureusement, il est trop tard pour rectifier cette erreur de conception, puisque la modification de la hiérarchie d'héritage, maintenant casser la compatibilité avec le code existant. A Stack
utilisé composition à la place de l'héritage, il peut toujours être modifié pour utiliser une autre structure de données sans violer l'API.
Je recommande fortement Josh Bloch livre Efficace Java 2nd Edition
- Article 16: Favoriser la composition au cours de l'héritage
- Article 17: la Conception et le document de l'héritage ou de l'autre de l'interdire
Bonne conception orientée objet n'est pas sur-le généreusement l'extension de classes existantes. Votre premier réflexe doit être de composer à la place.
Voir aussi:
Composition signifie HAS A
Hérédité IS A
Example
: La voiture a un Moteur et la Voiture est une Automobile
Dans la programmation, c'est représentée par:
class Engine {} // The engine class.
class Automobile{} // Automobile class which is parent to Car class.
// Car is an Automobile, so Car class extends Automobile class.
class Car extends Automobile{
// Car has a Engine so, Car class has an instance of Engine class as its member.
private Engine engine;
}
La réponse donnée par @Michael Rodrigues n'est pas correct (je m'excuse, je ne suis pas en mesure de commenter directement), et pourrait conduire à une certaine confusion. L'implémentation de l'Interface est une forme d'héritage... lors de l'implémentation d'une interface, vous n'êtes pas seulement hériter de tous les constantes, vous vous engagez votre objet du type spécifié par l'interface, c'est toujours un "est-un" de la relation. Si une voiture met en œuvre à Remplir, la voiture "est-un" à Remplir, et peut être utilisé dans votre code chaque fois que vous utilisez une Gourde.
La Composition est fondamentalement différente de l'héritage. Lorsque vous utilisez la composition, vous êtes (comme les autres réponses note) de faire un "a-un" de la relation entre deux objets, par opposition à l' "est-un" de la relation que vous faites lorsque vous utilisez l'héritage. Donc, à partir de la voiture des exemples pour les autres questions, si je voulais dire qu'une voiture "a-un" réservoir de gaz, je voudrais utiliser la composition, comme suit:
public class Car {
private GasTank myCarsGasTank;
}
J'espère que ça efface tout malentendu.
L'héritage apporte EST UNE relation. Composition apporte A-UNE relation.
Statergy tendance explique que la Composition doit être utilisé dans les cas où il y a des familles d'algorithmes de la définition d'un comportement particulier.
Exemple classique étant d'un canard de la classe qui implémente une mouche comportement.
public interface Flyable{
public void fly();
}
public class Duck {
Flyable fly;
public Duck(){
fly=new BackwardFlying();
}
}
Ainsi, nous pouvons avoir plusieurs classes qui implémentent volant par exemple:
public class BackwardFlying implements Flyable{
public void fly(){
Systemout.println("Flies backward ");
}
}
public class FastFlying implements Flyable{
public void fly(){
Systemout.println("Flies 100 miles/sec");
}
}
Avait-il été pour l'héritage que nous aurions deux classes différentes d'oiseaux qui mettent en œuvre la volée en fonction, encore et encore.ainsi, l'héritage et la composition sont complètement différents.
La Composition est juste comme il sonne - vous de créer un objet en le branchant dans les pièces.
MODIFIER le reste de cette réponse est, à tort, basée sur le postulat suivant.
Ceci est accompli avec les Interfaces.
Par exemple, à l'aide de l' Car
exemple ci-dessus,
Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel
Donc, avec un peu de la norme théorique des composants, vous pouvez construire votre objet. C'est votre travail pour remplir un House
protège ses occupants, et comment un Car
protège ses occupants.
L'héritage est comme l'autre manière autour. Vous commencez avec une complète (ou semi-complète) de l'objet et vous le remplacer ou Remplacer les divers éléments que vous souhaitez modifier.
Par exemple, MotorVehicle
peut venir avec un Fuelable
méthode et Drive
méthode. Vous pouvez laisser le Carburant méthode que c'est parce que c'est la même chose pour remplir une moto et une voiture, mais vous pouvez remplacer l' Drive
méthode parce que la Moto lecteurs très différemment à un Car
.
Avec l'héritage, certaines classes sont complètement mis en œuvre déjà, et d'autres méthodes qui vous êtes amené à remplacer. Avec la Composition rien n'est donné. (mais vous pouvez mettre en Œuvre les interfaces par des appels de méthodes dans d'autres classes, si vous avez quelque chose autour de la pose).
La Composition est considérée comme plus souple, parce que si vous avez une méthode telle que iUsesFuel, vous pouvez avoir une méthode à un autre endroit, une autre classe, un autre projet) qui vient de soucis à propos des relations avec les objets pouvant être alimenté, qu'il s'agisse d'une voiture, bateau, cuisinière, barbecue, etc. Interfaces mandat que les classes qui implémentent cette interface effectivement les méthodes de cette interface est tout au sujet. Par exemple,
iFuelable Interface:
void AddSomeFuel()
void UseSomeFuel()
int percentageFull()
ensuite, vous pouvez avoir une méthode quelque part d'autre
private void FillHerUp(iFuelable : objectToFill) {
Do while (objectToFill.percentageFull() <= 100) {
objectToFill.AddSomeFuel();
}
Étrange, par exemple, mais c'est la montre que cette méthode ne se soucie pas de ce qu'il se remplit, parce que l'objet implémente iUsesFuel
, il peut être rempli. Fin de l'histoire.
Si vous avez utilisé l'Héritage au lieu de cela, vous avez besoin de différents FillHerUp
méthodes MotorVehicles
et Barbecues
, sauf si vous avez eu assez bizarre "ObjectThatUsesFuel" objet de base à partir de laquelle hériter.