[JAVA] J'ai examiné les remplacements d'héritage de classe.

introduction

Mon junior m'a posé des questions sur l'héritage des classes Java, mais je n'ai pas pu y répondre immédiatement, j'ai donc fait beaucoup de recherches.

Origine

Ancienne salle de réunion @IT: à propos de l'héritage des variables

Extrait car il est difficile à lire

Lorsqu'une variable du même nom existe dans la superclasse, la méthode de la superclasse Lorsqu'elle est exécutée, la variable du même nom fait référence à la superclasse. Comment faire référence à une variable du même nom dans ma classe?

Voici un exemple de source. Ce que je pensais retournerait «Je suis un enfant» retournait «Je suis un parent».

Main.java


//Classe d'exécution
public class Main{
    public static void main(String args[]){
        Child c1 = new Child();
        c1.print(); 
    } 
} 

//Super classe
class Parent{
    private String JIBUN = "parent"; 
    public void print(){
        System.out.println("je" + JIBUN + "est."); 
    }
} 

//Classe enfant
class Child extends Parent{
    private String JIBUN = "les enfants";
}

Il a dit qu'il ne comprenait pas même s'il lisait l'explication.

À propos de l'héritage et de la surcharge Java

Au moment où je l'ai vu, j'ai pensé que JIBUN était privé, donc il ne peut pas être référencé à partir d'autres classes, et Parent et Child sont différents, non? C'était ça.

Mais que se passe-t-il s'il est protégé (public)? J'ai posé la question, alors je l'ai étudiée correctement.

Voici la source utilisée pour le test. piza.io

Main.java



//Classe d'exécution
public class Main{
    public static void main(String args[]){
        Child c1 = new Child();
        c1.print(); 
        c1.print2();
        Parent parent = new Child();
        c1.print(); 
        c1.print2();
    } 
} 

//Super classe
class Parent{
    private String JIBUN1 = "Parent 1"; 
    protected String JIBUN2 = "Parent 2"; 
    protected String JIBUN3 = "Parent 3"; 
    public void print(){ 
        System.out.println("print"); 
        System.out.println("je" + JIBUN1 + "est."); 
        System.out.println("je" + JIBUN2 + "est."); 
        System.out.println("je" + JIBUN3 + "est."); 
    }
//    final public void print2(){Si vous ne voulez pas le remplacer, ajoutez final et vous obtiendrez une erreur de compilation.
    public void print2(){
        System.out.println("print2"); 
        System.out.println("Parents" + JIBUN1 + "est."); 
        System.out.println("Parents" + JIBUN2 + "est."); 
        System.out.println("Parents" + JIBUN3 + "est."); 
    } 
} 

//Classe enfant
class Child extends Parent{
    // @Override //Erreur de compilation car elle ne peut pas être remplacée
    private String JIBUN1 = "Enfant 1";
    // @Override //Erreur de compilation car elle ne peut pas être remplacée
    protected String JIBUN2 = "Enfant 2";
    Child() {
        this.JIBUN3 = "Enfant 3";
    }
    @Override //L'annotation de remplacement indique clairement qu'il s'agit d'un remplacement
    public void print2(){
        System.out.println("print2"); 
        System.out.println("Enfants" + JIBUN1 + "est."); 
        System.out.println("Enfants" + JIBUN2 + "est."); 
        System.out.println("Enfants" + JIBUN3 + "est."); 
    } 
}

Résultat d'exécution

print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.

Les résultats sont résumés ci-dessous.

À propos de l'héritage et de la surcharge de C

En fait, j'ai initialement appris l'orientation objet en C #, donc c'était plus facile à écrire.

piza.io

Cette fois, il y a des substitutions et des masques de méthode, donc il y a print2 (remplacement) et print3 (masquage).

Main.cs


using System;

public class Test {
    public static void Main(){
        Child c1 = new Child(); 
        c1.print(); 
        c1.print2(); 
        c1.print3(); 
        Parent parent = new Child(); 
        parent.print(); 
        parent.print2(); 
        parent.print3(); 
    }
}

//Super classe
public class Parent{
    // virtual //Erreur de compilation car elle ne peut pas être remplacée
    private string JIBUN1 = "Parent 1"; 
    // virtual //Erreur de compilation car elle ne peut pas être remplacée
    protected string JIBUN2 = "Parent 2"; 
    // virtual //Erreur de compilation car elle ne peut pas être remplacée
    protected string JIBUN3 = "Parent 3";
    public void print(){ 
        Console.WriteLine("print"); 
        Console.WriteLine("je" + JIBUN1 + "est."); 
        Console.WriteLine("je" + JIBUN2 + "est."); 
        Console.WriteLine("je" + JIBUN3 + "est."); 
    } 
    virtual public void print2(){ 
        Console.WriteLine("print2"); 
        Console.WriteLine("Parents" + JIBUN1 + "est."); 
        Console.WriteLine("Parents" + JIBUN2 + "est."); 
        Console.WriteLine("Parents" + JIBUN3 + "est."); 
    }
    public void print3(){
        Console.WriteLine("print3"); 
        Console.WriteLine("Parents" + JIBUN1 + "est."); 
        Console.WriteLine("Parents" + JIBUN2 + "est."); 
        Console.WriteLine("Parents" + JIBUN3 + "est."); 
    } 
} 

//Classe enfant
public class Child : Parent{ 
    // override //Erreur de compilation car elle ne peut pas être remplacée
    private string JIBUN1 = "Enfant 1";
    // override //Erreur de compilation car elle ne peut pas être remplacée
    protected string JIBUN2 = "Enfant 2";
    public Child() {
        this.JIBUN3 = "Enfant 3";
    }
    override public void print2(){
        Console.WriteLine("print2"); 
        Console.WriteLine("Enfants" + JIBUN1 + "est."); 
        Console.WriteLine("Enfants" + JIBUN2 + "est."); 
        Console.WriteLine("Enfants" + JIBUN3 + "est."); 
    }
//    override public void print3(){Erreur de compilation car print3 n'a pas de virtual
    public void print3(){ //Juste une définition d'écrasement
        Console.WriteLine("print3"); 
        Console.WriteLine("Enfants" + JIBUN1 + "est."); 
        Console.WriteLine("Enfants" + JIBUN2 + "est."); 
        Console.WriteLine("Enfants" + JIBUN3 + "est."); 
    } 
}

Résultat de sortie

print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print3
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print3
Le parent est le parent 1.
Le parent est le parent 2.
Le parent est l'enfant 3.

Erreur de compilation (avertissement)

Compilation succeeded - 2 warning(s)
Main.cs(49,22): warning CS0108: `Child.JIBUN2' hides inherited member `Parent.JIBUN2'. Use the new keyword if hiding was intended
Main.cs(21,22): (Location of the symbol related to previous warning)
Main.cs(60,17): warning CS0108: `Child.print3()' hides inherited member `Parent.print3()'. Use the new keyword if hiding was intended
Main.cs(36,17): (Location of the symbol related to previous warning)

Les résultats sont résumés ci-dessous.

Eh bien, ce sentiment est une impression personnelle car il a été cultivé en C #.

À propos de l'héritage et de la surcharge C ++

Je n'ai pas sérieusement codé C ++, je vais donc essayer de le rechercher sur Google.

Il existe également print2 et print3 ici.

paiza.io

Main.cpp


#include <iostream>
using namespace std;

//Super classe
class Parent{
    private:
        // virtual //Erreur de compilation car elle ne peut pas être remplacée
        string JIBUN1 = "Parent 1";
    protected:
        // virtual //Erreur de compilation car elle ne peut pas être remplacée
        string JIBUN2 = "Parent 2"; 
        // virtual //Erreur de compilation car elle ne peut pas être remplacée
        string JIBUN3 = "Parent 3";
    public:
        void print() {
            cout << "print" << endl;
            cout << "je" + JIBUN1 + "est." << endl;
            cout << "je" + JIBUN2 + "est." << endl;
            cout << "je" + JIBUN3 + "est." << endl;
        };
        virtual void print2() {
            cout << "print2" << endl;
            cout << "Parents" + JIBUN1 + "est." << endl;
            cout << "Parents" + JIBUN2 + "est." << endl;
            cout << "Parents" + JIBUN3 + "est." << endl;
        }
        void print3() {
            cout << "print3" << endl;
            cout << "Parents" + JIBUN1 + "est." << endl;
            cout << "Parents" + JIBUN2 + "est." << endl;
            cout << "Parents" + JIBUN3 + "est." << endl;
        }
};

//Classe enfant
class Child : public Parent{ 
    private:
        string JIBUN1 // override //Erreur de compilation car elle ne peut pas être remplacée
        = "Enfant 1";
    protected:
        string JIBUN2 // override //Erreur de compilation car elle ne peut pas être remplacée
        = "Enfant 2";
        
    public:
        Child() {
            this->JIBUN3 = "Enfant 3";
        };
        void print2() override {
            cout << "print2" << endl;
            cout << "Enfants" + JIBUN1 + "est." << endl;
            cout << "Enfants" + JIBUN2 + "est." << endl;
            cout << "Enfants" + JIBUN3 + "est." << endl;
        }
        // void print3() override {Erreur de compilation car print3 n'a pas de virtual
        void print3() { //Juste une définition d'écrasement
            cout << "print3" << endl;
            cout << "Enfants" + JIBUN1 + "est." << endl;
            cout << "Enfants" + JIBUN2 + "est." << endl;
            cout << "Enfants" + JIBUN3 + "est." << endl;
        }
};

int main(void){
    Child *c1 = new Child();
    c1->print();
    c1->print2();
    c1->print3();
    Parent *parent = new Child();
    parent->print();
    parent->print2();
    parent->print3();
}

Résultat d'exécution

print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print3
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print
Je suis parent 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est l'enfant 2.
L'enfant est l'enfant 3.
print3
Le parent est le parent 1.
Le parent est le parent 2.
Le parent est l'enfant 3.

Il n'y a pas eu d'erreurs de compilation particulières (avertissements).

Les résultats sont résumés ci-dessous.

À propos de l'héritage et de la surcharge de python3

J'ai également étudié la langue LL à cette époque. La classe est python qui ressemble à une rénovation.

Puisque les hypothèses sont différentes, la source a une signification tout à fait différente. Pardon. (JIBUN1 et JIBUN2 sont des champs de classe)

Il y a ici aussi print2 et print3, mais ils sont identiques car ils ne peuvent pas être écrits séparément.

paiza.io

main.py


# coding: utf-8
# Your code here!

def main():
    c1 = Child()
    c1.print()
    c1.print2()
    c1.print3()

    parent = Parent()
    parent.print()
    parent.print2()
    parent.print3()

#Super classe
class Parent(object):
    JIBUN1 = "Parent 1"
    JIBUN2 = "Parent 2"
    def __init__(self):
        self.JIBUN3 = "Parent 3"
        
    def print(self):
        print("print")
        print("je" + self.JIBUN1 + "est.")
        print("je" + self.JIBUN2 + "est.")
        print("je" + self.JIBUN3 + "est.")

    def print2(self):
        print("print2")
        print("Parents" + self.JIBUN1 + "est.")
        print("Parents" + self.JIBUN2 + "est.")
        print("Parents" + self.JIBUN3 + "est.")

    def print3(self):
        print("print3")
        print("Parents" + self.JIBUN1 + "est.")
        print("Parents" + self.JIBUN2 + "est.")
        print("Parents" + self.JIBUN3 + "est.")
 

#Classe enfant
class Child(Parent):
    JIBUN1 = "Enfant 1"
    def __init__(self):
        super(Parent, self).__init__()
        self.JIBUN3 = "Enfant 3"

    def print2(self):
        print("print2")
        print("Enfants" + self.JIBUN1 + "est.")
        print("Enfants" + self.JIBUN2 + "est.")
        print("Enfants" + self.JIBUN3 + "est.")

    def print3(self):
        print("print3")
        print("Enfants" + self.JIBUN1 + "est.")
        print("Enfants" + self.JIBUN2 + "est.")
        print("Enfants" + self.JIBUN3 + "est.")

if __name__ == '__main__':
    main()

Résultat d'exécution

print
Je suis un enfant 1.
Je suis parent 2.
J'ai 3 enfants
print2
L'enfant est l'enfant 1.
L'enfant est parent 2.
L'enfant est l'enfant 3.
print3
L'enfant est l'enfant 1.
L'enfant est parent 2.
L'enfant est l'enfant 3.
print
Je suis parent 1.
Je suis parent 2.
Je suis parent 3
print2
Le parent est le parent 1.
Le parent est le parent 2.
Le parent est le parent 3.
print3
Le parent est le parent 1.
Le parent est le parent 2.
Le parent est le parent 3.

Les résultats sont résumés ci-dessous.

Eh bien, je pense que c'est facile à comprendre.

À propos de l'héritage et de la surcharge de rubis

Même dans le langage LL, ruby semble avoir conçu la classe depuis le début, donc pour référence. ruby Je viens de le gratter un peu.

C'est aussi une source avec une signification assez différente.

paiza.io

Main.rb


# coding: utf-8
# Your code here!

def main()
    c1 = Child.new
    c1.print
    c1.print2
    Child.print3

    parent = Parent.new
    parent.print
    parent.print2
    Parent.print3
end

#Super classe
class Parent
    @JIBUN1 = "Parent 1"
    @@JIBUN2 = "Parent 2"
    def initialize
        @JIBUN3 = "Parent 3"
    end
        
    def print
        p "print"
        p "je" + (@JIBUN1 || 'indéfini') + "est."
        p "je" + (@@JIBUN2 || 'indéfini') + "est."
        p "je" + @JIBUN3 + "est."
    end

    def print2
        p "print2"
        p "Parents" + (@JIBUN1 || 'indéfini') + "est."
        p "Parents" + (@@JIBUN2 || 'indéfini') + "est."
        p "Parents" + @JIBUN3 + "est."
    end

    def self.print3
        p "print3"
        p "Parents" + @JIBUN1 + "est."
        p "Parents" + @@JIBUN2 + "est."
        p "Parents" + (@JIBUN3 || 'indéfini') + "est."
    end
end
 

#Classe enfant
class Child < Parent
    @JIBUN1 = "Enfant 1"
    @@JIBUN2 = "Enfant 2"
    def initialize
        super
        @JIBUN3 = "Enfant 3"
    end

    def print2
        p "print2"
        p "Enfants" + (@JIBUN1 || 'indéfini') + "est."
        p "Enfants" + (@@JIBUN2 || 'indéfini') + "est."
        p "Enfants" + @JIBUN3 + "est."
    end

    def self.print3
        p "print3"
        p "Enfants" + (@JIBUN1 || 'indéfini') + "est."
        p "Enfants" + (@@JIBUN2 || 'indéfini') + "est."
        p "Enfants" + (@JIBUN3 || 'indéfini') + "est."
    end
end

main

Résultat d'exécution

"print"
"Je ne suis pas défini."
"J'ai 2 enfants"
"J'ai 3 enfants"
"print2"
"Les enfants ne sont pas définis."
"L'enfant est l'enfant 2."
"L'enfant est l'enfant 3."
"print3"
"L'enfant est l'enfant 1."
"L'enfant est l'enfant 2."
"Les enfants ne sont pas définis."
"print"
"Je ne suis pas défini."
"J'ai 2 enfants"
"Je suis parent 3"
"print2"
"Le parent n'est pas défini."
"Le parent est l'enfant 2."
"Le parent est le parent 3."
"print3"
"Le parent est le parent 1."
"Le parent est l'enfant 2."
"Le parent n'est pas défini."

Les résultats sont résumés ci-dessous.

Il semble qu'il a été conçu avec des classes, mais c'est un mystère pourquoi les variables de classe et les variables d'instance de classe sont devenues comme ça.

Résumé

Recommended Posts

J'ai examiné les remplacements d'héritage de classe.
Héritage de classe
[Python] Héritage de classe (super)
[Python] Héritage de classe, remplacement
[Django] J'ai essayé d'implémenter des restrictions d'accès par héritage de classe.
5 raisons pour lesquelles je suis entré dans Python
Héritage de classe et super fonction