[JAVA] Copiez et collez la source dans le développement de classe ...? C'est NON! Sachons "héritage"!

C'est le 4ème jour du Calendrier de l'Avent Stylez 2016. Au printemps 2016, j'étais encore un débutant Java et j'ai appris l'héritage pour la première fois ... C'est l'article que je résumais à l'époque.

Bases de l'héritage

1. Le problème de la copie lors du développement d'une classe similaire

Si vous écrivez un programme volumineux, vous devrez peut-être créer une classe similaire à celle que vous avez créée précédemment. Dans un tel cas, si vous copiez et collez le code d'origine et ajoutez une nouvelle fonction, les inconvénients suivants se produiront.

2. Résolution par héritage

Une fonction appelée ** héritage ** permet de créer des classes similaires tout en évitant les inconvénients qui surviennent lors de la création de classes similaires par copier-coller.

Hériter et créer une classe.java


//Classe dont vous souhaitez hériter
Public class Hero {
    private String name = "Courageux";
    Private int hp = 100;

    //échapper
  public void run(){
      System.out.println(name + "Échappé!");
    }
}

//Je veux hériter de la classe Hero et devenir un héros plus fort ...
Public Class SuperHero extends Hero { //Point 1
    public void attack(Matango m){
      System.out.println(name + "Attaque!");
      m.hp -= 5;
      System.out.println("Infligé 5 points de dégâts!");
      }
}

Définir une classe avec héritage.java


Le nom de la classe étend le nom de la classe d'origine{
Avec la classe parent"Différence"membre
}

--Lors de la définition d'une classe qui utilise l'héritage, écrivez les membres de la différence, tels que les membres que vous souhaitez ajouter à la classe parent (la classe qui est la source de l'héritage), dans la classe enfant (la classe nouvellement définie).

Par conséquent, dans la classe SuperHero qui hérite de la classe Hero, non seulement la méthode attack () définie dans la classe SuperHero mais aussi la méthode run () de la classe Hero peuvent être appelées.

3. Comment exprimer la relation d'héritage

Dans l'exemple, la classe SuperHero a été créée en héritant de la classe Hero. La relation entre ces deux classes est appelée ** relation d'héritage **, et la relation d'héritage peut être exprimée comme suit. hero (classe parent, super classe)super-héros (classe enfant, sous-classe)

4. Variations d'héritage

L'héritage peut également définir de nombreuses classes enfants basées sur une classe parent. Cependant, ** Il n'est pas possible de définir une classe enfant qui hérite de plusieurs classes parentes (héritage multiple). ** **

5. Remplacer

Lorsqu'il y a une situation où vous souhaitez redéfinir un membre défini dans la classe parent dans la classe enfant, vous pouvez remplacer le membre de la classe parent par la classe enfant. Cela s'appelle ** override **.

** ◎ Membres déclarés dans les classes enfants à l'aide de l'héritage ** (1) Si la classe parente n'a pas le même membre, ce membre devient un membre "ajouté". (2) Si la classe parente a le même membre, ce membre devient un membre à "écraser".

6. Interdiction d'héritage et dérogation

Classes qui ne peuvent pas être héritées.java


public final class String extends Object....

Méthodes qui ne peuvent pas être remplacées.java


public final void slip()....

Apparence de l'instance

Classe SuperHero créée sur la base de l'héritage ... Cette instance contient une instance Hero à l'intérieur et a une ** double structure ** dans son ensemble. Avec cette structure à l'esprit, comprenons divers appels et principes de fonctionnement.

1. Appel d'une méthode

2. Accès à la partie d'instance parent

--Lorsque vous devez accéder à la partie d'instance parente, vous pouvez accéder à la partie d'instance parente à partir de la partie d'instance enfant en utilisant ** super **, qui est un mot réservé pour la partie d'instance parente.

◎ Utilisez le champ de la partie d'instance parent

super.Nom de domaine


 ◎ Appelez la méthode de la partie d'instance parent

#### **`super.Nom de la méthode(argument)`**
```Nom de la méthode(argument)


 --super.run () appelle la méthode run () de la partie d'instance parent, mais si vous écrivez run (), elle a la même signification que "this.run ()", et run () défini par vous-même. Appelez la méthode.

 * Lorsque trois classes, classe A (grands-parents), classe B (parent) et classe C (soi), ont une relation d'héritage, la classe c peut accéder à la classe parente classe B, mais à la classe A, qui est le grand-parent. Il n'est pas accessible directement.

# Héritage et constructeur
### 1. Comment créer une classe à l'aide de l'héritage
 Lors de la création d'une instance de la classe SuperHero qui hérite de la classe Hero, le constructeur SuperHero est appelé, mais en fait, le constructeur Hero hérité est également appelé à ce stade.
 → ** Java a une règle selon laquelle "tous les constructeurs doivent appeler le constructeur de la partie d'instance interne au début" **, donc ce comportement est effectué.

 - À l'origine, vous devez écrire super (argument); sur la première ligne du constructeur.
 --Si le programmeur oublie d'écrire super (argument);, le compilateur ajoutera automatiquement super ();.

### 2. Situation dans laquelle la partie d'instance parent ne peut pas être créée
 Comme expliqué dans "1. Comment créer une classe en utilisant l'héritage", super (); sera ajouté automatiquement même si vous oubliez de l'écrire.
 Cependant, le super (); généré automatiquement tente d'appeler le constructeur de la classe parent sans argument.

 À ce stade, s'il n'y a pas de constructeur pouvant être appelé sans argument dans le constructeur existant dans l'instance parente, il n'y a aucun constructeur qui peut être appelé et cela provoque une erreur.

### 3. Spécifiez l'argument constructeur de l'instance interne.
 L'appel a échoué car aucun constructeur ne pouvait être appelé sans argument. Que faire ...

 ◎ Spécifiez l'argument lors de l'appel du constructeur.
```public item (string name){ ```
 Si vous voulez appeler le constructeur, vous pouvez appeler le constructeur correctement en prenant un argument comme super ("juste une barre");.
 À ce stade, faites attention au type et au nombre d'arguments du constructeur à appeler.

# Héritage correct, mauvais héritage
### 1. est-un principe
 L'héritage correct est ** l'héritage qui suit une règle appelée «est-un principe» **

 ◎ est-une relation
 La classe enfant est une classe parent (la classe enfant est une sorte de classe parent)
 A est-un B signifie "A est un type de B"

 Essayez de faire une phrase d'is-a lors de l'héritage, et si ce n'est pas naturel, l'héritage est faux.
 ◎ Règles d'utilisation de l'héritage
 Si le principe de is-a ne tient pas, vous ne devriez pas utiliser l'héritage même si vous pouvez le faire facilement.

### 2. Pourquoi vous ne devriez pas faire le mauvais héritage

 Il y a deux raisons pour lesquelles vous ne devriez pas utiliser l'héritage qui n'est pas une relation is-a.

 - À l'avenir, lorsque vous élargirez la classe, il y aura un conflit avec le monde réel.
 ――Parce que vous ne pourrez pas utiliser la "diversité", la dernière des trois principales fonctions orientées objet.

### 3. Relation de généralisation / spécialisation
 Être connecté par la relation est-un signifie que plus il y a de classes enfants, plus elles sont «spéciales et concrètes», et plus les classes parentes sont, plus «générales, abstraites et ambiguës». Il sera généralisé (généralisé) aux «choses».

 ――Si vous vous spécialisez, vous pouvez définir des champs et des méthodes en détail, et le nombre de membres augmentera.
 ――Il devient difficile de définir des champs et des méthodes détaillés.

 L'héritage est à la fois un «outil pour réduire les descriptions de code en double» et un outil pour «montrer que deux classes ont une relation de spécialisation / généralisation».


Recommended Posts

Copiez et collez la source dans le développement de classe ...? C'est NON! Sachons "héritage"!
À propos de next () et nextLine () de la classe Scanner
À propos de l'héritage de classe.
Différences entre les classes et les instances dans Ruby
À propos du chargement et de l'initialisation des classes au démarrage de la JVM
[Ruby] Imbrication de classes, héritage et principes de base de soi