Héritage Java

À propos de cet article

Je me réfère à la 2ème édition de l'introduction de Java que vous pouvez comprendre clairement.

1. Bases de l'héritage

1.1 Héritage

Lors du développement d'un programme, il arrive souvent qu'une classe similaire à la classe précédemment créée soit créée. Pour le moment, il est inefficace de copier et coller la classe créée précédemment, vous pouvez donc écrire du code efficace en héritant de la classe créée précédemment.

Hero.java


public class Hero{
  private String name = "hoge";
  private int Hp = 100;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 5;
  }
}

SuperHero.java


public class SuperHero{
  private String name = "hoge";
  private int Hp = 100;
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("L'état du vol");
  }
  public void land(){
    this.flying = false;
    System.out.println("Condition d'atterrissage");
  }
}

Dans ce code, lorsque j'ajoute une nouvelle méthode à la classe Hero, je dois également modifier cette modification en classe SuperHero. Étant donné que la plupart du code est similaire entre la classe SuperHero et la classe Hero, la vue d'ensemble est difficile et la maintenance est gênante. Par conséquent, utilisez ** l'héritage ** pour éliminer la duplication de code.

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("L'état du vol");
  }
  public void land(){
    this.flying = false;
    System.out.println("Condition d'atterrissage");
  }
}

En réécrivant comme décrit ci-dessus, il est possible de définir une classe SuperHero qui hérite des méthodes de champ de la classe Hero. Dans ce cas, la classe Hero est appelée la classe parent (super classe) et la classe SuperHero est appelée la classe enfant (sous-classe).

1.2 Variations d'héritage

Java n'autorise pas l'héritage multiple. Plus précisément, s'il existe une classe Hero et une classe Moster, il n'est pas possible de définir une classe HeroMonster en héritant de ces deux classes. Autrement dit, il n'est pas possible de définir une classe enfant avec une pluralité de classes parent en tant que parents. Il est possible de remplacer la méthode définie dans la classe parente par la classe enfant (appelée substitution de méthode). Certaines classes Java ne sont pas autorisées à hériter. Un exemple est la classe String. Il est également possible de déclarer une classe qui ne lui permet pas d'être héritée d'elle-même. Ajoutez l'opérateur final lors de la déclaration d'une classe.

Main.java


public final class Main{
  public static void main(Strign args[]){
    //Contenu de la fonction principale
  }
}

De même, pour éviter les remplacements de méthode, ajoutez l'opérateur final lors de la déclaration de la méthode.

1.3 Comportement de l'instance

Considérez ce qui arrive au comportement de l'instance créée en raison de l'héritage. Il sera décrit en utilisant la classe Hero montrée ci-dessus et la classe SuperHero. L'instance SuperHero contient une instance Hero à l'intérieur et a une structure double. Lorsqu'une commande d'exécution de méthode est appelée depuis l'extérieur de l'instance, l'instance multi-structurée appelle * autant que possible la méthode * de l'instance enfant à l'extérieur. Plus précisément, lorsque la méthode de récupération est appelée à partir de l'instance SuperHero, la méthode remplacée est appelée et la méthode de récupération de l'instance Hero n'est pas appelée. Décrit l'accès à l'instance parent. Comme spécification supplémentaire, si vous récupérez en vol, vous récupérerez Hp de 25 points. Lors de l'appel du champ de méthode de l'instance parent

super. Nom de la méthode (argument) nom du champ super

Et.

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
    if(this.flying){
      super.recover();
    }
  }
  public void fly(){
    this.flying = true;
    System.out.println("L'état du vol");
  }
  public void land(){
    this.flying = false;
    System.out.println("Condition d'atterrissage");
  }
}

À ce stade, si vous appelez super.recover () avec recover (), il sera appelé comme this.recover () et vous entrerez dans une boucle infinie, alors soyez prudent.

1.4 Héritage et constructeurs

Nous avons déjà expliqué que les instances héritées ont une structure multicouche. Ensuite, considérez comment l'instance est créée. Exécutez le programme suivant en vous référant au programme ci-dessus.

Hero.java


public class Hero{
  private String name = "hoge";
  private int Hp = 100;

  public void attack(Monster m){
    m.hp -= 5;
  }
  public void recover(){
    this.Hp += 5;
  }

  Hero(){
    System.out.println("Constructeur de héros");
  }
}

SuperHero.java


public class SuperHero extends Hero{
  private boolean flying;

  public void attack(Monster m){
    m.hp -= 10;
  }  
  public void recover(){
    this.Hp += 20;
  }
  public void fly(){
    this.flying = true;
    System.out.println("L'état du vol");
  }
  public void land(){
    this.flying = false;
    System.out.println("Condition d'atterrissage");
  }

  SuperHero(){
    System.out.println("Constructeur SuperHero");
  }
}

Main.java


public class Main{
  public static void main(Strign args[]){
    SuperHero sh = new SuperHero();
  }
}

Tout d'abord, la partie d'instance parent est créée, puis la partie d'instance enfant est créée à l'extérieur. Enfin, la JVM appelle automatiquement le constructeur de classe SuperHero. Le résultat de l'exécution est le suivant.

Résultat d'exécution


Constructeur de héros
Constructeur SuperHero

Notez que le constructeur de l'instance Hero, qui est l'instance interne, est également appelé. En effet, la règle Java est «Tous les constructeurs doivent appeler le constructeur de l'instance interne au début».

SuperHero.java


public class SuperHero extends Hero{
  .
  .
  .

  SuperHero(){
    super();
    System.out.println("Constructeur SuperHero");
  }
}

Le compilateur insère automatiquement super ().

1.5 Situations où une instance parente ne peut pas être créée

Un constructeur qui n'est pas défini dans la partie d'instance parent peut être appelé par le constructeur dans la partie d'instance enfant, ce qui entraîne une erreur. Plus précisément, il sera décrit en utilisant la classe Human et la classe Soldier.

Human.java


public class Human{
  private String name;
  private int Hp;
  private int Mp;

  Human(String name){
    this.name = name;
    this.Hp = 100;
    this.Mp = 100;
  }
  Human(String name, int hp, int mp){
    this.name = name;
    this.Hp = hp;
    this.Mp = mp;
  }
}

Human.java


public class Soldier{
  .
  .
  .
}

Main.java


public class Main{
  public static void main(Strign args[]){
    Soldier soldier = new Soldier();
  }
}

Dans ce code, la classe Soldier n'a pas de constructeur, donc le constructeur de la classe parent classe Human est appelé. Cependant, la classe Human n'a pas de constructeur sans argument, donc ce code entraînera une erreur. Pour éviter cela, appelez de force le constructeur avec des arguments dans le constructeur de la classe Soldier pour résoudre le problème.

Human.java


public class Soldier{
  .
  .
  .
  Soldier(){
    super("hoge");
  }
}

1.6 Héritage correct et héritage incorrect

L'héritage correct est l'héritage selon le «principe est-un».

La classe enfant est une classe parent (la classe enfant fait partie de la classe parent)

Expliqué dans le code ci-dessus, la classe SuperHero fait partie de la classe Hero. C'est une erreur que la classe Hero fasse partie de la classe SuperHero. L'héritage est une fonctionnalité utile, mais un héritage incorrect peut conduire à des incohérences programmatiques et à l'incapacité de tirer parti de la diversité.

2. Héritage à l'aide de classes abstraites

2.1 Signification de l'existence d'une classe abstraite

Une classe abstraite est une classe qui a un champ de méthode abstraite. Une classe concrète qui hérite d'une classe abstraite doit remplacer les méthodes définies dans la classe abstraite. De plus, lors de l'héritage de plusieurs classes abstraites, cela peut être réalisé en définissant les classes abstraites comme des interfaces (les détails sont 2.3). L'importance de l'existence de classes et de méthodes abstraites est un matériau pour créer efficacement des programmes sûrs lorsque le nombre de développeurs augmente à l'avenir. Pour donner un exemple concret, si vous procédez au développement sans classe abstraite, le contenu d'une certaine méthode peut ne pas être décidé à ce stade, et le contenu de la méthode peut être laissé vide. Lorsqu'un autre développeur voit cette méthode, je ne sais pas si le contenu doit être réécrit. Cependant, si elle est définie comme une méthode abstraite, elle doit être écrasée, afin que l'on puisse voir que le contenu doit être réécrit. A partir de là, il est possible de se développer en toute confiance en utilisant la méthode abstraite.

2.2 Méthode de classe abstraite

Character.java


public class Character{
  .
  .
  public abstract void atttack(Monster m);

}

La méthode d'attaque est incorporée dans une classe qui hérite de la classe Character.

Character.java


public abstract class Character{
  .
  .
  public abstract void atttack(Monster m);

}

Définissez une classe en tant que classe abstraite pour empêcher la création d'instances de classe incomplètes.

2.3 Interface

En Java, les classes abstraites avec un degré d'abstraction particulièrement élevé peuvent être traitées spécialement comme des interfaces. Comme condition à traiter comme interface

--Toutes les méthodes sont des méthodes abstraites

Il y a.

Creature.java



public interface Creature{
  public abstract void run();  //le résumé public peut être omis
}

Si vous définissez une variable dans l'interface, public static final est complété et traité comme une constante. Lors de l'implémentation de la classe Creature, procédez comme suit.

Pig.java



public class Pig implements Creature{
  public void run(){
    System.out.println("Cochon s'est enfui");
  }
}

En définissant l'interface

Il y a un mérite.

Recommended Posts

[Java] Héritage
Héritage Java
Héritage Java
java (héritage)
[Java] Héritage de classe
À propos de l'héritage Java
[Java] Surcharge / Remplacer / Héritage
Héritage
Résumer l'héritage Java (Java Silver 8)
À propos de l'héritage (Java Silver)
Java
Java
[Java] Mémo d'héritage implicite
Mémo d'apprentissage Java (héritage)
Résumé d'héritage avancé, interface -java
Héritage de l'interface de l'historique d'apprentissage JAVA
Java à partir de débutant, héritage
[Java] Qu'est-ce que l'héritage de classe?
java (héritage du principe is-a)
Apprendre Java (0)
Étudier Java ―― 3
[Java] tableau
Java protégé
[Java] Annotation
Module [Java]
Étudier Java ―― 9
Java scratch scratch
Astuces Java, astuces
Méthodes Java
Méthode Java
java (constructeur)
À propos de l'héritage
Tableau Java
[Java] ArrayDeque
java (remplacement)
java (méthode)
Journée Java 2018
Chaîne Java
java (tableau)
Java statique
Sérialisation Java
java débutant 4
JAVA payé
Étudier Java ―― 4
Java (ensemble)
tri shell java
[Java] compareTo
Étudier Java -5
java réfléchissant 获 获 举
java (interface)
Mémorandum Java
Tableau Java
Étudier Java ―― 1
[Java] Array
[Java] Polymorphisme
Étudier Java # 0
Revue Java
framework java
Fonctionnalités Java
FastScanner Java
Fonctionnalités Java