web-dev-qa-db-fra.com

Constructeurs et héritages par défaut en Java

J'ai une question sur les constructeurs par défaut et l'héritage en Java. 

Généralement, si vous écrivez une classe et n’incluez aucun constructeur, Java vous fournit automatiquement un constructeur par défaut (sans paramètres), qui initialise toutes les variables d’instance de la classe (s’il en existe) avec des valeurs par défaut (0, null , ou fausse). Cependant, si vous écrivez un constructeur avec certains paramètres et que vous n'écrivez aucun constructeur par défaut, Java ne fournit pas de constructeur par défaut. Ma question est la suivante: quel est le cas des classes qui héritent d'autres classes - si j'écris un constructeur avec certains paramètres, mais n'inclue pas de constructeur par défaut, héritent-ils du constructeur par défaut de la super classe ?

50
user42155
  1. Si vous ne créez pas de constructeur, le constructeur vide par défaut est automatiquement créé .

  2. Si un constructeur n'appelle pas explicitement un super ou ce constructeur comme première instruction, un appel à super () est automatiquement ajouté .

Toujours.

61
paulmurray

Les constructeurs ne sont pas hérités.

En outre, l'initialisation des champs est effectuée par la machine virtuelle et non par le constructeur par défaut. Le constructeur par défaut appelle simplement le constructeur par défaut de la superclasse, et le constructeur par défaut de Object est vide. Le point positif de cette conception est qu’il n’ya aucun moyen d’accéder aux champs non initialisés.

52
starblue

Sauf si vous utilisez super (...), un constructeur appelle le constructeur vide de son parent . Remarque: il le fait sur toutes vos classes, même celles qui étendent Object.

Ceci n'hérite pas, les sous-classes n'obtiennent pas les mêmes constructeurs avec les mêmes arguments. Cependant, vous pouvez ajouter des constructeurs qui appellent l'un des constructeurs de la super classe.

11
Peter Lawrey

La règle de base est un appel (ou une invocation) à un constructeur doit être la première instruction que JVM doit exécuter,

Ainsi, lorsque vous avez une super classe avec uniquement un constructeur paramétré et aucun constructeur par défaut, et que la classe de base n’appelle pas explicitement le constructeur paramétré de la super classe, JVM fournit le super (); call qui génère une erreur car il n'y a pas de constructeur par défaut pour la super-classe; nous fournissons donc un constructeur par défaut dans la super-classe ou nous appelons explicitement le constructeur paramétré de la super-classe dans le constructeur de la classe de base. lorsque nous donnons l'appel explicite, la machine virtuelle Java ne se donne pas la peine de mettre la ligne super (); as constructeur invocation devrait être la première déclaration de la méthode, ce qui ne peut pas arriver (à cause de notre appel explicite).

6
Abhishek Nair

La section 8.8.9 de la spécification du langage Java explique en détail ce qui se passe:

Si une classe ne contient aucune déclaration de constructeur, alors un constructeur par défaut est implicitement déclaré. La forme du constructeur default pour une classe de niveau supérieur, La classe membre ou la classe locale est la suivante:

  • Le constructeur par défaut a la même accessibilité que la classe (§6.6).
  • Le constructeur par défaut n'a pas de paramètre formel, sauf dans un .__ non privé. classe membre interne, où le constructeur par défaut déclare implicitement un formel paramètre représentant l'instance immédiatement englobante de la classe (§8.8.1, §15.9.2, §15.9.3).
  • Le constructeur par défaut n'a pas de clause de projection.
  • Si la classe en cours de déclaration est la classe primordiale Object, la valeur par défaut Le constructeur a un corps vide. Sinon, le constructeur par défaut simplement invoque le constructeur de la superclasse sans arguments.

Vous pouvez voir qu'il n'y a pas d'héritage ici: tout ce qu'il y a à faire, c'est la "magie du compilateur" avec le constructeur par défaut implicitement déclaré. La spécification précise également que le constructeur par défaut est ajouté uniquement lorsque la classe n'a aucun constructeur, ce qui signifie que la réponse à votre question est "non": une fois que vous avez attribué à une classe un constructeur, l'accès au constructeur par défaut de son la super-classe est perdue.

5
dasblinkenlight

Si vous fournissez un constructeur, Java ne vous générera pas de constructeur vide par défaut. Ainsi, votre classe dérivée ne pourra appeler que votre constructeur.

Le constructeur par défaut n'initialise pas vos variables privées aux valeurs par défaut. La preuve en est qu'il est possible d'écrire une classe qui n'a pas de constructeur par défaut et dont les membres privés sont initialisés aux valeurs par défaut. Voici un exemple:

public class Test {

    public String s;
    public int i;

    public Test(String s, int i) {
        this.s = s;
        this.i = i;
    }

    public Test(boolean b) {
        // Empty on purpose!
    }

    public String toString() {
        return "Test (s = " + this.s + ", i = " +  this.i + ")";
    }

    public static void main (String [] args) {
        Test test_empty = new Test(true);
        Test test_full = new Test("string", 42);
        System.out.println("Test empty:" + test_empty);
        System.out.println("Test full:"  + test_full);
    }
}
3
potyl

La réponse à votre question est très simple. Implicitement (Invisible), la première instruction d'un constructeur est 'super ();' C'est-à-dire l'appel du constructeur sans paramètre de la super classe, jusqu'à ce que vous le changiez explicitement en quelque chose comme: ) 'etc .' this (); ' est le constructeur de la classe actuelle.

2
Ashish

La règle du pouce est que la classe secondaire doit appeler n'importe quel constructeur de la classe de base. Donc, si vous n'avez pas la valeur par défaut, appelez celle qui existe déjà depuis la sous-classe. sinon, implémentez la constante vide dans la classe de base pour éviter le problème de compilation

2
Muthu N

Lorsque nous ne créons pas de constructeur, Java crée automatiquement un constructeur par défaut . Mais lorsque nous créons un ou plusieurs constructeurs personnalisés avec des arguments, Java ne crée aucun constructeur par défaut . Si nous créons un ou plusieurs constructeurs et nous voulons créer un objet sans aucun argument de constructeur, nous devons déclarer un constructeur vide.

1
Thusitha

Tout constructeur de la sous-classe appellera le constructeur sans argument (ou constructeur par défaut) de la classe parent. Si vous définissez un constructeur paramétré dans la classe parent, vous devez appeler explicitement le constructeur de la classe parent avec le mot clé super. Sinon, l'erreur de compilation sera générée.

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Le code ci-dessus donnera l'erreur de compilation:

prog.Java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
    { 
    ^
  required: int,int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error

L'erreur ci-dessus s'est produite parce que nous n'avons aucun constructeur constructeur/constructeur par défaut dans la classe parente ni que nous appelons le constructeur paramétré depuis la sous-classe.

Maintenant, pour résoudre ce problème, appelez le constructeur paramétré comme ceci:

class Alpha 
{ 
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        super(4, 5); // calling the parameterized constructor of parent class
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

Sortie

base
derived

ou

définissez un constructeur sans argument dans la classe parente comme ceci:

class Alpha 
{ 
    Alpha(){

    }
    Alpha(int s, int p) 
    { 
        System.out.println("base");
    }

} 

public class SubAlpha extends Alpha 
{ 
    SubAlpha() 
    { 
        System.out.println("derived"); 
    } 
    public static void main(String[] args) 
    { 
        new SubAlpha(); 
    } 
}

sortie

derived 
0
Anmol Middha

Il y aura une erreur de compilation ... car le compilateur recherche le constructeur par défaut de la super-classe et si ce n’est pas là ... c’est une erreur ... et le programme ne compile pas ...

0
Shubham Soni