Concept de poo pour les débutants: qu’est-ce que L’héritage?
L’héritage est l’un des concepts de base des langages de programmation orientée objet (POO). C’est un mécanisme où vous pouvez dériver une classe à partir d’une autre classe pour une hiérarchie de classes qui partagent un ensemble d’attributs et de méthodes.
Vous pouvez l’utiliser pour déclarer différents types d’exceptions, ajouter une logique personnalisée aux frameworks existants et même mapper votre modèle de domaine à une base de données.,
Déclarer une hiérarchie d’héritage
En Java, chaque classe ne peut être dérivée d’une autre classe. Cette classe est appelée une superclasse ou une classe parente. La classe dérivée est appelée sous-classe ou classe enfant.
Vous utilisez le mot-clé extends pour identifier la classe que votre sous-classe étend. Si vous ne déclarez pas de superclasse, votre classe étend implicitement l’objet class. Object est la racine de toutes les hiérarchies d’héritage; c’est la seule classe en Java qui n’étend pas une autre classe.
le diagramme et les extraits de code suivants montrent un exemple de hiérarchie d’héritage simple.,
la classe BasicCoffeeMachine ne déclare pas de superclasse et étend implicitement l’objet de classe. Vous pouvez cloner L’exemple de projet CoffeeMachine sur GitHub.
la classe PremiumCoffeeMachine est une sous-classe de la classe BasicCoffeeMachine.
modificateurs D’héritage et d’accès
Les modificateurs d’accès définissent quelles classes peuvent accéder à un attribut ou à une méthode. Dans l’un de mes précédents articles sur l’encapsulation, je vous ai montré comment vous pouvez les utiliser pour implémenter un mécanisme de dissimulation d’informations. Mais ce n’est pas le seul cas où vous devez vous familiariser avec les différents modificateurs., Ils affectent également les entités et les attributs auxquels vous pouvez accéder dans une hiérarchie d’héritage.
Voici un aperçu rapide des différents modificateurs:
- les attributs ou méthodes privés ne sont accessibles qu’au sein de la même classe.
- Les attributs et méthodes sans modificateur d’accès sont accessibles dans la même classe, et par toutes les autres classes du même paquet.
- les attributs ou méthodes protégés sont accessibles dans la même classe, par toutes les classes du même paquet et par toutes les sous-classes.,
- les attributs et méthodes publics sont accessibles à toutes les classes.
comme vous pouvez le voir dans cette liste, une sous-classe peut accéder à tous les attributs et méthodes protégés et publics de la superclasse. Si la sous-classe et la superclasse appartiennent au même package, la sous-classe peut également accéder à tous les attributs et méthodes privés de package de la superclasse.
je le fais deux fois dans le constructeur de la classe PremiumCoffeeMachine.
j’utilise d’abord le mot-clé super pour appeler le constructeur de la superclasse. Le constructeur est public et la sous-classe peut y accéder., Le mot-clé super fait référence à la superclasse. Vous pouvez l’utiliser pour accéder à un attribut ou pour appeler une méthode de la superclasse qui est remplacée par la sous-classe actuelle. Mais plus à ce sujet dans la section suivante.
l’attribut protégé configMap est défini par la classe BasicCoffeeMachine. En étendant cette classe, l’attribut fait également partie de la classe PremiumCoffeeMachine, et je peux ajouter la configuration requise pour préparer un expresso à la carte.,
method overriding
L’héritage ajoute non seulement toutes les méthodes publiques et protégées de la superclasse à votre sous-classe, mais il vous permet également de remplacer leur implémentation. La méthode de la sous-classe remplace alors celle de la superclasse. Ce mécanisme est appelé polymorphisme.
je l’utilise dans la classe PremiumCoffeeMachine pour étendre les capacités de brassage du café de la machine à café. La méthode brewCoffee de la méthode BasicCoffeeMachine ne peut préparer que du café filtre.
je remplace cette méthode dans la classe PremiumCoffeeMachine pour ajouter le support de CoffeeSelection.,ESPRESSO. Comme vous pouvez le voir dans l’extrait de code, le mot-clé super est très utile si vous substituez une méthode. La méthode brewCoffee de la BasicCoffeeMachine gère déjà la sélection du café.FILTER_COFFEE et lance une CoffeeException pour les CoffeeSelections non prises en charge.
je peux réutiliser cela dans ma nouvelle méthode brewCoffee. Au lieu de réimplémenter la même logique, je vérifie simplement si le CoffeeSelection est ESPRESSO. Si ce n’est pas le cas, j’utilise le mot-clé super pour appeler la méthode brewCoffee de la superclasse.,
empêcher le remplacement d’une méthode
Si vous voulez vous assurer qu’aucune sous-classe ne peut modifier l’implémentation d’une méthode, vous pouvez la déclarer définitive. Dans l’exemple de cet article, je l’ai fait pour la méthode addBeans de la classe BasicCoffeeMachine.
c’est souvent une bonne idée de rendre finales toutes les méthodes appelées par un constructeur. Il empêche toute sous-classe de modifier, souvent involontairement, le comportement du constructeur.,
une sous-classe est également du type de sa superclasse
une sous-classe hérite non seulement des attributs et des méthodes de la superclasse, mais elle hérite également des types de la superclasse. Dans l’exemple, BasicCoffeeMachine est de type BasicCoffeeMachine et Object. Et un objet PremiumCoffeeMachine est des types PremiumCoffeeMachine, BasicCoffeeMachine et Object.
pour cette raison, vous pouvez lancer un objet PremiumCoffeeMachine pour taper BasicCoffeeMachine.
BasicCoffeeMachinee coffeeMachine = (BasicCoffeeMachine) PremiumCoffeeMachine(beans);
qui vous permet d’écrire du code qui utilise la superclasse et de l’exécuter avec toutes les sous-classes.,
dans cet exemple, le code de la méthode createCoffeeMachine renvoie et la méthode makeCoffee utilise la classe BasicCoffeeMachine. Mais la méthode createCoffeeMachine instancie un nouvel objet PremiumCoffeeMachine. Lorsqu’il est renvoyé par la méthode, l’objet est automatiquement converti en BasicCoffeeMachine et le code peut appeler toutes les méthodes publiques de la classe BasicCoffeeMachine.
l’objet coffeeMachine est converti en BasicCoffeeMachine, mais c’est toujours un PremiumCoffeeMachine., Ainsi, lorsque la méthode makeCoffee appelle la méthode brewCoffee, elle appelle la méthode overridden sur la classe PremiumCoffeeMachine.
définition des classes abstraites
Les classes abstraites sont différentes des autres classes dont nous avons parlé. Ils peuvent être étendus, mais pas instanciés. Qui le rend idéal pour représenter des généralisations conceptuelles qui n’existent pas dans votre domaine spécifique, mais vous permettent de réutiliser des parties de votre code.
Vous utilisez le mot-clé abrégé de déclarer une classe ou une méthode abstraite. Une classe abstraite n’a pas besoin de contenir de méthodes abstraites., Mais une méthode abstraite doit être déclarée par une classe abstraite.
refactorisons l’exemple de machine à café et introduisons la classe AbstractCoffeeMachine en tant que superclasse de la classe BasicCoffeeMachine. Je déclare Cette classe comme abstraite et définit la méthode abstraite brewCoffee.
public abstract class AbstractCoffeeMachine { protected Map<CoffeeSelection, Configuration> configMap; public AbstractCoffeeMachine() { this.configMap = new HashMap<CoffeeSelection, Configuration>(); } public abstract Coffee brewCoffee(CoffeeSelection selection) throws CoffeeException; }
comme vous pouvez le voir, Je ne fournis pas le corps de la méthode abstraite brewCoffee. Je le déclare simplement comme je le ferais dans une interface., Lorsque vous étendez la classe AbstractCoffeeMachine, vous devrez définir la sous-classe comme abstraite ou remplacer la méthode brewCoffee pour implémenter le corps de la méthode.
je fais quelques modifications mineures à la classe BasicCoffeeMachine. Il étend maintenant la classe AbstractCoffeeMachine, et la méthode brewcoffee déjà existante remplace la méthode abstraite de la superclasse.
Une autre chose que j’ai changée est le constructeur de la classe BasicCoffeeMachine. Il appelle maintenant le constructeur de la superclasse et ajoute une paire clé-valeur à l’attribut configMap sans instancier la carte., Il est défini et instancié par la superclasse abstraite et peut être utilisé dans toutes les sous-classes.
C’est l’une des principales différences entre une super-classe abstraite et une interface. La classe abstract vous permet non seulement de déclarer des méthodes, mais vous pouvez également définir des attributs qui ne sont pas statiques et finaux.
Summary
comme vous l’avez vu, l’héritage est un concept puissant qui vous permet d’implémenter une sous-classe qui étend une superclasse. Ce faisant, la sous-classe hérite de tous les attributs et méthodes protégés et publics, ainsi que des types de la superclasse., Vous pouvez ensuite utiliser les attributs hérités de la superclasse, utiliser ou remplacer les méthodes héritées et convertir la sous-classe en n’importe quel type de sa superclasse.
Vous pouvez utiliser une classe abstraite pour définir une abstraction générale qui ne peut pas être instanciée. Dans cette classe, vous pouvez déclarer des méthodes abstraites qui doivent être remplacées par des sous-classes non abstraites. Cela est souvent utilisé si l’implémentation de cette méthode est spécifique à chaque sous-classe, mais que vous souhaitez définir une API générale pour toutes les classes de la hiérarchie.