Je me réfère à la 2ème édition de l'introduction de Java que vous pouvez comprendre clairement.
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).
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.
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.
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 ().
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");
}
}
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é.
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.
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.
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