Il y a un dicton dans « Think in Java » : la réutilisation du code est l'une des nombreuses fonctionnalités accrocheuses de Java. Mais pour qu'un langage soit hautement révolutionnaire, il ne suffit pas de pouvoir copier du code et de le modifier ; il faut qu'il soit capable de faire plus. La chose la plus frappante dans cette phrase est "réutiliser le code". Réutiliser le code autant que possible est ce que nous, les programmeurs, avons recherché. Je vais maintenant présenter un moyen de réutiliser le code, qui est également l'une des trois caractéristiques majeures de Java. .Un ---Héritage.
Héritage
Avant d'expliquer, jetons un coup d'œil à un exemple. Cet exemple est tiré du billet de blog précédent (Amélioration Java - Comprendre l'encapsulation des trois fonctionnalités majeures de Java).
De là, nous pouvons voir que les classes Femme et Mari sont toutes les mêmes à l'exception de leurs maris et femmes respectifs. En tant que programmeur qui souhaite maximiser la réutilisation du code, nous pouvons le faire. Je ne supporte pas un code aussi répété. S'il y a une autre maîtresse, maîtresse, maîtresse ou maîtresse... (je vais trop loin), est-ce qu'on est obligé de l'écrire comme ça ? Alors, comment parvenir à la réutilisabilité de ces classes ? Profitez de l'héritage ! !
Tout d'abord, quittons le monde de la programmation logicielle. Par bon sens, nous savons que les maris, les femmes, les maîtresses... ce sont tous des personnes, et ils ont tous des choses en commun, comme. comme le nom, l'âge, le sexe, la tête, etc., et ils sont tous capables de manger, de marcher, de parler et d'autres comportements courants, donc à partir de là, nous pouvons constater qu'ils possèdent tous des attributs et des comportements humains, et qu'ils héritent également de ces attributs et comportements des humains.
À partir de ce qui précède, nous pouvons essentiellement comprendre le concept d'héritage. L'héritage est une technologie qui utilise la définition d'une classe existante comme base pour créer une nouvelle classe. La définition d'une nouvelle classe peut ajouter de nouvelles données ou. nouvelles fonctions. Vous pouvez également utiliser les fonctions de la classe parent, mais vous ne pouvez pas hériter de manière sélective de la classe parent. En utilisant l'héritage, nous pouvons réutiliser le code précédent très facilement, ce qui peut grandement améliorer l'efficacité du développement.
Après avoir utilisé l'héritage pour l'épouse et le mari, en plus de réduire la quantité de code, nous pouvons également voir clairement leur relation.
L'héritage décrit la relation "est-un". S'il y a deux objets A et B, s'il peut être décrit comme "A est B", cela peut signifier que A hérite de B, où B est hérité. le successeur est appelé classe parent ou superclasse, et le successeur est appelé sous-classe ou classe dérivée.
En fait, le successeur est une spécialisation de l'héritier. En plus d'avoir les caractéristiques de l'héritier, il a aussi ses propres caractéristiques uniques. Par exemple, les chats ont des caractéristiques que les autres animaux n’ont pas, comme attraper des souris et grimper aux arbres. En même temps, dans la relation successorale, l'héritier peut remplacer complètement l'héritage, mais pas l'inverse. Par exemple, on peut dire qu'un chat est un animal, mais on ne peut pas dire que l'animal est un chat. la raison pour laquelle nous appelons cette « transformation vers le haut », présentée ci-dessous.
Il est vrai que l'héritage définit la façon dont les classes se rapportent les unes aux autres et partagent des caractéristiques. Pour plusieurs classes identiques ou familières, nous pouvons résumer leurs comportements ou attributs communs et les définir comme une classe parent ou une super classe, puis utiliser ces classes pour hériter de la classe parent. Elles peuvent non seulement avoir les propriétés et les méthodes de la classe parent. Vous pouvez également définir vos propres propriétés ou méthodes uniques.
En même temps, vous devez vous souvenir de trois phrases lorsque vous utilisez l'héritage :
1. La sous-classe a les attributs et méthodes non privés de la classe parent.
2. Les sous-classes peuvent avoir leurs propres attributs et méthodes, c'est-à-dire que les sous-classes peuvent étendre les classes parentes.
3. Les sous-classes peuvent implémenter les méthodes de la classe parent à leur manière. (Introduit plus tard).
En résumé, l'utilisation de l'héritage présente de nombreux avantages. En plus de placer les attributs communs de toutes les sous-classes dans la classe parent pour réaliser le partage de code et éviter la duplication, elle peut également modifier et étendre l'implémentation héritée. .
Il est vrai qu'en matière d'héritage, ces trois choses sont indispensables : constructeur, mot-clé protégé et transformation ascendante.
Constructeur
Nous savons d'après ce qui précède que les sous-classes peuvent hériter des attributs et des méthodes des classes parentes. En plus de ces classes privées, il y a une autre chose dont les sous-classes ne peuvent pas hériter : les constructeurs. Les constructeurs peuvent uniquement être appelés et ne peuvent pas être hérités. Pour appeler la méthode constructeur de la classe parent, on peut utiliser super().
Pour les sous-classes, l'initialisation correcte de son constructeur est très importante, et si et seulement s'il n'existe qu'une seule méthode qui puisse garantir cela : appeler le constructeur de la classe parent dans le constructeur pour terminer l'initialisation, et le parent Le constructeur de classe possède toutes les connaissances et capacités nécessaires pour effectuer l’initialisation de la classe parent.
public class Person { protected String name; protected int age; protected String sex; Person(){ System.out.println("Person Constrctor..."); } } public class Husband extends Person{ private Wife wife; Husband(){ System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor... Husband Constructor...
Cet exemple montre que le processus de construction se propage "vers l'extérieur" à partir de la classe parent, c'est-à-dire en partant de la classe parent et en complétant la construction étape par étape jusqu'à la sous-classe. Et nous n'avons pas explicitement référencé le constructeur de la classe parent. C'est l'astuce de Java : le compilateur appellera par défaut le constructeur de la classe parent de la sous-classe.
Cependant, cet appel par défaut au constructeur de la classe parent est un prérequis : la classe parent possède un constructeur par défaut. Si la classe parent n'a pas de constructeur par défaut, nous devons explicitement utiliser super() pour appeler le constructeur de la classe parent, sinon le compilateur signalera une erreur : un constructeur conforme à la forme de la classe parent est introuvable.
public class Person { protected String name; protected int age; protected String sex; Person(String name){ System.out.println("Person Constrctor-----" + name); } } public class Husband extends Person{ private Wife wife; Husband(){ super("chenssy"); System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor-----chenssy Husband Constructor...
Donc pour résumer : pour l'héritage, la sous-classe appellera le constructeur de la classe parent par défaut, mais s'il n'y a pas de constructeur de classe parent par défaut, la sous-classe doit spécifier explicitement le constructeur de la classe parent, et doit être la première chose faite dans le constructeur de sous-classe (la première ligne de code).
mot-clé protégé
Le modificateur d'accès privé est le meilleur choix pour l'encapsulation, mais cela n'est basé que sur un monde idéal. Parfois, nous avons besoin de ce besoin : nous devons le faire. cacher certaines choses au monde autant que possible, tout en permettant aux membres des sous-classes d'y accéder. À ce stade, vous devez utiliser protected.
Pour protected, cela indique qu'il est privé en ce qui concerne l'utilisateur de la classe, mais pour toute sous-classe qui hérite de cette classe ou de toute autre classe située dans le même package, elle est accessible en privé.
public class Person { private String name; private int age; private String sex; protected String getName() { return name; } protected void setName(String name) { this.name = name; } public String toString(){ return "this name is " + name; } /** 省略其他setter、getter方法 **/ } public class Husband extends Person{ private Wife wife; public String toString(){ setName("chenssy"); //调用父类的setName(); return super.toString(); //调用父类的toString()方法 } public static void main(String[] args) { Husband husband = new Husband(); System.out.println(husband.toString()); } } Output: this name is chenssy
À partir de l'exemple ci-dessus, vous pouvez voir que la sous-classe Husband peut évidemment appeler setName() de la classe parent Person.
Il est vrai que même si vous pouvez utiliser le modificateur d'accès protégé pour limiter l'accès aux propriétés et méthodes de la classe parent, le meilleur moyen est de garder les propriétés privées (nous devrions toujours continuer à modifier l'implémentation sous-jacente) et d'utiliser la méthode protégée pour contrôler les autorisations d'accès pour les héritiers d'une classe.
Transformation vers le haut
Dans l'héritage ci-dessus, nous avons parlé de l'héritage comme d'une relation mutuelle entre is-a, l'héritage du chat et des animaux, nous pouvons donc dire chat C'est un animal, ou un chat est un type d'animal. Considérer les chats comme des animaux de cette manière, c'est se transformer vers le haut. Comme suit :
public class Person { public void display(){ System.out.println("Play Person..."); } static void display(Person person){ person.display(); } } public class Husband extends Person{ public static void main(String[] args) { Husband husband = new Husband(); Person.display(husband); //向上转型 } }
Ici, nous passons Person.display(husband). Il ressort de cette phrase que le mari est un type de personne.
La conversion d'une sous-classe en classe parent se déplace vers le haut dans la relation d'héritage, c'est pourquoi on l'appelle généralement transformation vers le haut. Puisque la conversion ascendante est une conversion d'un type spécialisé vers un type plus général, elle est toujours sûre. Le seul changement qui peut survenir est la perte de propriétés et de méthodes. C'est pourquoi le compilateur autorise les conversions vers le haut même si la conversion n'est pas explicitement exprimée ou si aucun indicateur spécial n'est spécifié.
Soyez prudent avec l'héritage
Ce qui précède a parlé des nombreux avantages de l'héritage, pouvons-nous donc utiliser l'héritage de manière libérale ? Un conseil pour vous : utilisez l’héritage avec prudence.
Tout d'abord, nous devons préciser que l'héritage présente les défauts suivants :
1. Lorsque la classe parent change, la sous-classe doit changer.
2. L'héritage détruit l'encapsulation Pour la classe parent, ses détails d'implémentation sont transparents pour la sous-classe.
3. L'héritage est une relation de couplage forte.
Ainsi, lorsque nous utilisons l'héritage, nous devons nous assurer que l'utilisation de l'héritage est effectivement une méthode efficace et réalisable. Alors faut-il recourir à l’héritage ? "Think in Java" apporte une solution : demandez-vous si vous devez effectuer une transformation ascendante de la sous-classe vers la classe parent. Si une transformation vers le haut est nécessaire, un héritage est nécessaire, mais sinon, vous devez soigneusement réfléchir si vous avez besoin d'un héritage.
Utilisez l'héritage avec prudence ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
Ce qui précède est le chapitre sur l'amélioration de Java (2) ----- comprendre l'héritage des trois caractéristiques majeures de Java Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php. cn) !