class Dad
{
protected static String me = "dad";
public void printMe()
{
System.out.println(me);
}
}
class Son extends Dad
{
protected static String me = "son";
}
public void doIt()
{
new Son().printMe();
}
La fonction doIt affichera "papa". Existe-t-il un moyen de le faire imprimer "fils"?
java
inheritance
overriding
Dikla
la source
la source
Réponses:
Oui. Mais comme la variable est concernée, elle est écrasée (Donner une nouvelle valeur à la variable. Donner une nouvelle définition à la fonction est Remplacer).
Just don't declare the variable but initialize (change) in the constructor or static block.
La valeur sera reflétée lors de l'utilisation dans les blocs de la classe parent
si la variable est statique alors changez la valeur lors de l'initialisation elle-même avec un bloc statique,
ou bien changer de constructeur.
Vous pouvez également modifier la valeur ultérieurement dans n'importe quel bloc. Cela se reflétera dans la super classe
la source
class Son extends Dad { static { me = 'son' } }
En bref, non, il n'y a aucun moyen de remplacer une variable de classe.
Vous ne remplacez pas les variables de classe en Java, vous les masquez. Le remplacement concerne par exemple les méthodes. Le masquage est différent du dépassement.
Dans l'exemple que vous avez donné, en déclarant la variable de classe avec le nom 'me' dans la classe Son, vous masquez la variable de classe qu'elle aurait héritée de sa superclasse Dad avec le même nom 'me'. Cacher une variable de cette manière n'affecte pas la valeur de la variable de classe «me» dans la superclasse Dad.
Pour la deuxième partie de votre question, sur la façon de faire imprimer "fils", je définirais la valeur via le constructeur. Bien que le code ci-dessous s'écarte beaucoup de votre question initiale, je l'écrirais quelque chose comme ceci;
Le JLS donne beaucoup plus de détails sur le masquage dans la section 8.3 - Déclarations sur le terrain
la source
Person
censée remplacer dans cet exemple?Son
etDad
sont censés hériter dePerson
, puis appelersuper("Son or Dad");
leurs constructeurs.Oui, remplacez simplement la
printMe()
méthode:la source
printMe()
méthode, ou même si elle a cette méthode, c'est une méthode statique?Vous pouvez créer un getter, puis remplacer ce getter. C'est particulièrement utile si la variable que vous remplacez est une sous-classe d'elle-même. Imaginez que votre super classe a un
Object
membre mais que dans votre sous-classe, il est désormais plus défini pour être unInteger
.la source
Si vous prévoyez de le remplacer, je ne vois pas de raison valable de garder ce statique. Je suggérerais l'utilisation de l'abstraction (voir l'exemple de code). :
Maintenant, nous pouvons ajouter le papa:
le fils:
et papa a rencontré une gentille dame:
On dirait que nous avons une famille, disons au monde leurs noms:
}
System.out Sortie: Tommy Nancy Dad
System.err est le même que ci-dessus (a juste une police rouge)
Sortie JOption:
Tommy puis
Nancy puis
papa
la source
Cela ressemble à un défaut de conception.
Supprimez le mot-clé static et définissez la variable par exemple dans le constructeur. De cette façon, Son définit simplement la variable sur une valeur différente dans son constructeur.
la source
Bien qu'il soit vrai que les variables de classe ne peuvent être masquées que dans les sous-classes et ne pas être remplacées, il est toujours possible de faire ce que vous voulez sans remplacer
printMe ()
dans les sous-classes, et la réflexion est votre ami. Dans le code ci-dessous, j'omets la gestion des exceptions pour plus de clarté. Veuillez noter que déclarerme
asprotected
ne semble pas avoir beaucoup de sens dans ce contexte, car il va être caché dans les sous-classes ...la source
... affichera "son".
la source
https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
Ça s'appelle Hiding Fields
À partir du lien ci-dessus
la source
uniquement en remplaçant
printMe()
:la référence à
me
dans laDad.printMe
méthode pointe implicitement vers le champ statiqueDad.me
, donc d'une manière ou d'une autre vous changez ce quiprintMe
fait dansSon
...la source
Vous ne pouvez pas remplacer les variables d'une classe. Vous ne pouvez remplacer que les méthodes. Vous devriez garder les variables privées sinon vous pouvez avoir beaucoup de problèmes.
la source
Il imprime en effet «papa», puisque le champ n'est pas écrasé mais masqué. Il existe trois approches pour le faire imprimer 'fils':
Approche 1: remplacer printMe
Approche 2: ne pas masquer le champ et l'initialiser dans le constructeur
Approche 3: utiliser la valeur statique pour initialiser un champ dans le constructeur
la source
Les variables ne participent pas au remplacement. Seules les méthodes le font. Un appel de méthode est résolu au moment de l'exécution, c'est-à-dire que la décision d'appeler une méthode est prise au moment de l'exécution, mais les variables ne sont décidées qu'au moment de la compilation. Par conséquent, cette variable est appelée dont la référence est utilisée pour l'appel et non de l'objet d'exécution.
Jetez un œil à l'extrait suivant:
Lorsque vous exécutez le code, la console affichera:
la source
Bien sûr, utiliser des attributs privés, des getters et des setters serait la chose recommandée à faire, mais j'ai testé ce qui suit, et cela fonctionne ... Voir le commentaire dans le code
Sooo ... ai-je juste redéfini les règles d'héritage ou ai-je mis Oracle dans une situation délicate? Pour moi, la chaîne statique protégée me est clairement remplacée, comme vous pouvez le voir lorsque vous exécutez ce programme. En outre, cela n'a aucun sens pour moi pourquoi les attributs ne devraient pas être remplaçables.
la source
Pourquoi voudriez-vous remplacer les variables alors que vous pourriez facilement les réaffecter dans les sous-classes.
Je suis ce modèle pour travailler autour de la conception du langage. Supposons un cas où vous avez une classe de service lourde dans votre framework qui doit être utilisée dans différentes saveurs dans plusieurs applications dérivées.Dans ce cas, la meilleure façon de configurer la logique de la super classe est de réaffecter ses variables de `` définition ''.
la source
Les variables de classe (également applicables aux variables d'instance) ne présentent pas de fonction de remplacement en Java car les variables de classe sont appelées sur la base du type d'objet appelant. Ajout d'une classe supplémentaire (Human) dans la hiérarchie pour la rendre plus claire. Alors maintenant nous avons
Fils étend papa étend l'humain
Dans le code ci-dessous, nous essayons d'itérer sur un tableau d'objets Humain, Papa et Fils, mais il imprime les valeurs de Classe Humaine dans tous les cas car le type d'objet appelant était Humain.
Imprimera
Si nous voulons accéder à la variable de classe de l'objet réel à partir d'une variable de référence de sa classe parent, nous devons le dire explicitement au compilateur en convertissant la référence parent (objet humain) en son type.
Imprimera
Sur la partie de cette question: - Comme déjà suggéré, remplacez la méthode printMe () dans la classe Son, puis en appelant
La variable de classe de papa "me" sera masquée car la déclaration la plus proche (de la méthode printme () de la classe Son) du "moi" (dans la classe Son) aura la priorité.
la source
Appelez simplement super.variable dans le constructeur de sous-classe
La sortie est de 10.
la source