Impossible de trouver un meilleur titre.
Un exemple d'apprentissage classique: la classe Humain
, où les propriétés sont le nom, l'âge, la mère et le père. Les deux parents sont également Humains
.
Human() { this("Jack", 22); } Human(int age, String name) { this(age, name, new Human()); // new Human() will cause SOF Error. } Human(int age, String name, Human mother) { this.age = age; this.name = name; this.mother = mother; }
Je veux créer 3 constructeurs:
Humain ()
; Humain (nom de la chaîne, âge entier)
; Human (String name, int age, Human mother)
. Je suppose je comprends comment fonctionne le chaînage, et c'est ce que j'ai fait:
public class Human { String name; int age; Human mother; }
Comme mentionné ci-dessus, je recevoir StackOverflowError
, encore une fois, je suppose je sais pourquoi c'est arrivé. Bien que pour être honnête, j'ai pensé que j'obtiendrais quelque chose comme Human Jack où sa mère est aussi Human Jack .
Néanmoins, je me demande comment cela devrait être fait. Je suppose qu'au lieu de new Human ()
, je devrais appeler le constructeur avec tous les paramètres, mais je ne suis pas sûr que ce soit vrai et la seule option disponible.
J'apprécierai des conseils ici.
5 Réponses :
Oui, vous avez raison sur la raison pour laquelle cela se produit. Juste pour être sûr, cependant:
new Human ()
appelle this ("Jack", 22)
this ("Jack", 22)
appelle this (age, name, new human ())
nouvel humain ()
qui appelle this ("Jack", 22)
à nouveau this (age, name, new human ())
La bonne façon de procéder est de vous assurer que vous ne revenez pas là où vous avez commencé. Donc, si vous utilisez new Human (String)
ou new Human (String, int)
dans l'un de vos constructeurs, vous devez être sûr que ce constructeur ( new Human (String)
ou new Human (String, int)
) n'utilise pas aussi new Human (String)
ou new Human (String, int)
, car vous finirez par récurer à l'infini. Vous devez utiliser new Human (String, int, Human)
quelque part. Ainsi par exemple:
Human(int age, String name) { this(age, name, null); }
Bien sûr, cela signifie que la nouvelle instance aura null
pour mère
. P >
C'est une excellente réponse! Apprécier ton aide.
Human() { this.name = "Jack"; this.age = 22; } Human(int age, String name) { this.age = age; this.name = name; this.mother = null; } Human(int age, String name, Human mother) { this.age = age; this.name = name; this.mother = mother; } This will not create any hirarical or nested constructor
Si je comprends bien votre question, il y a deux sous-questions:
Concernant la première question, un constructeur est une méthode, votre implémentation aboutit à deux méthodes récursives. Vous devez casser la récursive ou introduire une condition sortante. Il y a une autre option - appelez this (age, name, null)
dans le premier constructeur.
Concernant la deuxième question, une solution populaire est le modèle usine simple
, où vous n'avez qu'un seul constructeur privé avec tous les paramètres, puis quelques méthodes d'usine publiques pour fais ce que tu veux.
merci, c'est une excellente réponse! Besoin d'en savoir plus sur la solution usine simple
.
Votre constructeur Human (int, String)
fait une récursion sans aucune condition qui à la fin crée une StackOverflowError
.
La surcharge du constructeur est un moyen très courant de fournir des moyens pratiques de créer un objet. Tant que les membres ne sont pas définitifs
et peuvent être manipulés plus tard, vous devriez mieux ne transmettre aucune valeur (aka null
) au lieu de créer plus d'objets à la volée. P >
En réalité, il n'y a pas d'humain sans mère , mais cela peut être inconnu, donc passer null
pour l'instant serait la meilleure approche ici.
Si vous avez besoin de la mère immuable, vous ne devez fournir aucun constructeur sans référence pour que la mère le rende clairement visible. Même cela ne fonctionnera pas car vous ne pouvez pas fournir une structure arborescente sans fin au début de l'humanité. En règle générale, ces structures ont un objet "racine" qui n'a pas de parent (ou mère dans cet exemple).
appréciez une réponse aussi détaillée!
Je suggérerais au lieu d'aller au chaînage du constructeur. Je préférerais par exemple le chaînage de variables et utiliser un modèle de conception de constructeur avec une structure de données de type nœud.
Class Human{ int age; Sting name; Human mother; public Human setAge(int age){ this.age = age; return this; } public Human setName(String name){ this.name = name; return this; } public Human setHuman(Human mother){ this.mother= mother; return this; } }
Après cela, vous pouvez créer la première instance Mother en tant qu'humain, puis définir comme un humain chez l'enfant. faites le moi savoir pour une réponse plus précise.
c'est une nouvelle approche! Merci.
Il existe une version de bocal lambok également disponible pour cette approche. Si vous êtes intéressé, nous vous donnerons plus de détails sur le pot lambok
new Human ()
appellethis ("Jack", 22)
qui appelle ensuitenew Human (age, name)
qui appelle ensuitenew Human ()
à nouveau. Par conséquent, Stackoverflow.Est-il vraiment logique qu'un humain ait des valeurs par défaut?