Ceci est une question d'entrevue.
Les sous-classes héritent-elles des champs privés?
J'ai répondu "Non", car nous ne pouvons pas y accéder en utilisant la "voie OOP normale". Mais l'intervieweur pense qu'ils sont hérités, car on peut accéder à ces champs indirectement ou en utilisant la réflexion et ils existent toujours dans l'objet.
Après mon retour, j'ai trouvé la citation suivante dans le javadoc :
Membres privés dans une superclasse
Une sous-classe n'hérite pas des membres privés de sa classe parente.
Connaissez-vous des arguments pour l'opinion de l'intervieweur?
java
oop
inheritance
private
Stan Kurilin
la source
la source
Réponses:
La plus grande partie de la confusion dans les questions / réponses entoure la définition de l'héritage.
Évidemment, comme l'explique @DigitalRoss, un OBJET d'une sous-classe doit contenir les champs privés de sa superclasse. Comme il le déclare, ne pas avoir accès à un membre privé ne signifie pas qu'il n'est pas là.
Toutefois. C'est différent de la notion d'héritage pour une classe. Comme c'est le cas dans le monde java, où il y a une question de sémantique, l'arbitre est la Java Language Specification (actuellement 3ème édition).
Comme l'indique le JLS ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ):
Cela répond à la question exacte posée par l'intervieweur: "les sous- classes héritent-elles des champs privés". (emphase ajoutée par moi)
La réponse est non. Ce n'est pas le cas. Les OBJETS des sous-classes contiennent des champs privés de leurs superclasses. La sous-classe elle-même n'a AUCUNE NOTION de champs privés de sa superclasse.
S'agit-il d'une sémantique de nature pédante? Oui. Est-ce une question d'entrevue utile? Probablement pas. Mais le JLS établit la définition du monde Java, et il le fait (dans ce cas) sans ambiguïté.
EDITED (suppression d'une citation parallèle de Bjarne Stroustrup qui, en raison des différences entre java et c ++, ne fait qu'ajouter à la confusion. Je vais laisser ma réponse reposer sur le JLS :)
la source
Oui
Il est important de réaliser que s'il existe deux classes, il n'y a qu'un seul objet.
Donc, oui, bien sûr, il a hérité des champs privés. Ils sont, vraisemblablement, essentiels pour une fonctionnalité d'objet appropriée, et bien qu'un objet de la classe parent ne soit pas un objet de la classe dérivée, une instance de la classe dérivée est surtout définitivement une instance de la classe parent. Ça ne pourrait pas être très bien sans tous les champs.
Non, vous ne pouvez pas y accéder directement. Oui, ils sont hérités. Ils doivent l' être.
C'est une bonne question!
Mettre à jour:
Euh, "non"
Eh bien, je suppose que nous avons tous appris quelque chose. Étant donné que le JLS est à l'origine du libellé exact "non hérité", il est correct de répondre "non" . Étant donné que la sous-classe ne peut pas accéder ou modifier les champs privés, en d'autres termes, ils ne sont pas hérités. Mais il vraiment est juste un objet, il a vraiment fait contenir les champs privés, et donc si quelqu'un prend les JLS et formulation tutoriel dans le mauvais sens, il sera assez difficile de comprendre la POO, les objets Java, et ce qui se passe réellement.
Mettre à jour pour mettre à jour:
La controverse implique ici une ambiguïté fondamentale: de quoi s'agit-il exactement? L' objet? Ou parlons-nous dans un certain sens de la classe elle-même? Une grande latitude est permise lors de la description de la classe par opposition à l'objet. Ainsi, la sous-classe n'hérite pas de champs privés, mais un objet qui est une instance de la sous-classe contient certainement les champs privés.
la source
car
, il le gardait dans unprivate
casier dont l'enfant n'a pas la clé. Vous héritez en effet ducar
mais c'est inutile pour vous. Donc, pratiquement, vous ne bénéficiez pas de l'héritage.Non. Les champs privés ne sont pas hérités ... et c'est pourquoi Protected a été inventé. C'est par conception. Je suppose que cela justifiait l'existence d'un modificateur protégé.
Venons-en maintenant aux contextes. Qu'entendez-vous par hérité - s'il se trouve dans l'objet créé à partir d'une classe dérivée? Oui, ça l'est.
Si vous voulez dire, peut-il être utile pour une classe dérivée. Et bien non.
Maintenant, lorsque vous arrivez à la programmation fonctionnelle, le domaine privé de la super classe n'est pas hérité de manière significative pour la sous-classe . Pour la sous-classe, un champ privé de super classe est identique à un champ privé de toute autre classe.
Fonctionnellement, ce n'est pas hérité. Mais idéalement , ça l'est.
OK, je viens de regarder le tutoriel Java, ils citent ceci:
voir: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
Je suis d'accord, que le champ est là. Mais, la sous-classe n'obtient aucun privilège sur ce champ privé. Pour une sous-classe, le champ privé est identique à tout champ privé de toute autre classe.
Je pense que c'est uniquement une question de point de vue. Vous pouvez modeler l'argument de chaque côté. Il vaut mieux justifier dans les deux sens.
la source
I believe it's purely matter of point-of-view.
etjustified the existence of protected modifier.
Cela dépend de votre définition de «hériter». La sous-classe a-t-elle toujours les champs en mémoire? Absolument. Peut-il y accéder directement? Non. Ce ne sont que des subtilités de la définition; il s'agit de comprendre ce qui se passe réellement.
la source
Je vais démontrer le concept avec du code. Les sous-classes héritent en fait des variables privées de la super classe. Le seul problème est qu'ils ne sont pas accessibles aux objets enfants à moins que vous ne fournissiez des getters et setters publics pour les variables privées dans la super classe.
Considérez deux classes dans le paquetage Dump. L'enfant étend le parent.
Si je me souviens bien, un objet enfant en mémoire se compose de deux régions. L'un est la partie parent uniquement et l'autre est la partie enfant uniquement. Un enfant peut accéder à la section privée dans le code de son parent uniquement via une méthode publique dans le parent.
Pense-y de cette façon. Le père de Borat, Boltok, a un coffre-fort contenant 100 000 $. Il ne veut pas partager son coffre à variables "privé". Donc, il ne fournit pas de clé pour le coffre-fort. Borat hérite du coffre-fort. Mais à quoi ça sert s'il ne peut même pas l'ouvrir? Si seulement son père avait fourni la clé.
Parent -
Enfant -
la source
Non, ils n'en héritent pas.
Le fait qu'une autre classe puisse l'utiliser indirectement ne dit rien sur l'héritage, mais sur l'encapsulation.
Par exemple:
Vous pouvez également obtenir la valeur de l'
count
intérieurUseIt
via la réflexion. Cela ne signifie pas que vous en héritez.METTRE À JOUR
Même si la valeur est là, elle n'est pas héritée par la sous-classe.
Par exemple, une sous-classe définie comme:
C'est exactement la même situation que le premier exemple. L'attribut
count
est masqué et n'est pas hérité du tout de la sous-classe. Pourtant, comme le souligne DigitalRoss, la valeur est là, mais pas par héritage.Mets le comme ça. Si votre père est riche et vous donne une carte de crédit, vous pouvez toujours acheter quelque chose avec son argent, mais cela ne signifie pas que vous avez hérité de tout cet argent, n'est-ce pas?
Autre mise à jour
Il est cependant très intéressant de savoir pourquoi l'attribut est là.
Franchement, je n'ai pas le terme exact pour le décrire, mais c'est la machine virtuelle Java et la façon dont elle fonctionne qui charge également la définition parent "non héritée".
Nous pourrions en fait changer le parent et la sous-classe fonctionnera toujours.
Par exemple :
Je suppose que le terme exact pourrait être trouvé ici: La spécification de la machine virtuelle JavaTM
la source
encapsulation
vsinherit
, je suppose que cette réponse mérite un vote plus élevé.Eh bien, ma réponse à la question de l'intervieweur est - Les membres privés ne sont pas hérités dans les sous-classes mais ils sont accessibles à la sous-classe ou à l'objet de la sous-classe uniquement via des méthodes getter ou setter publiques ou toute autre méthode appropriée de classe originale. La pratique normale est de garder les membres privés et d'y accéder en utilisant des méthodes getter et setter qui sont publiques. Quel est donc l'intérêt de n'hériter des méthodes getter et setter que lorsque le membre privé avec lequel ils traitent n'est pas disponible pour l'objet? Ici, «hérité» signifie simplement qu'il est disponible directement dans la sous-classe pour jouer avec les méthodes nouvellement introduites dans la sous-classe.
Enregistrez le fichier ci-dessous sous ParentClass.java et essayez-le vous-même ->
Si nous essayons d'utiliser la variable privée x de ParentClass dans la méthode de SubClass, elle n'est pas directement accessible pour toute modification (signifie non héritée). Mais x peut être modifié dans SubClass via la méthode setX () de la classe d'origine comme dans la méthode setXofParent () OU il peut être modifié en utilisant l'objet ChildClass en utilisant la méthode setX () ou la méthode setXofParent () qui appelle finalement setX (). Donc, ici setX () et getX () sont en quelque sorte des portes vers le membre privé x d'une ParentClass.
Un autre exemple simple est Clock superclass a des heures et des minutes en tant que membres privés et des méthodes getter et setter appropriées en tant que public. Vient ensuite DigitalClock en tant que sous-classe d'horloge. Ici, si l'objet de DigitalClock ne contient pas de membres heures et minutes, les choses sont foutues.
la source
Ok, c'est un problème très intéressant. J'ai fait beaucoup de recherches et suis arrivé à la conclusion que les membres privés d'une superclasse sont en effet disponibles (mais pas accessibles) dans les objets de la sous-classe. Pour le prouver, voici un exemple de code avec une classe parent et une classe enfant et j'écris un objet de classe enfant dans un fichier txt et je lis un membre privé nommé 'bhavesh' dans le fichier, prouvant ainsi qu'il est effectivement disponible dans l'enfant mais pas accessible en raison du modificateur d'accès.
Ouvrez MyData1.txt et recherchez le membre privé nommé «bhavesh». Faites-moi savoir ce que vous en pensez.
la source
Il semblerait qu'une sous-classe hérite des champs privés dans la mesure où ces mêmes champs sont utilisés dans le fonctionnement interne de la sous-classe (philosophiquement parlant). Une sous-classe, dans son constructeur, appelle le constructeur de la superclasse. Les champs privés de superclasse sont évidemment hérités par la sous-classe appelant le constructeur de superclasse si le constructeur de superclasse a initialisé ces champs dans son constructeur. Ce n'est qu'un exemple. Mais bien sûr, sans méthodes d'accesseur, la sous-classe ne peut pas accéder aux champs privés de la superclasse (c'est comme ne pas pouvoir ouvrir le panneau arrière d'un iPhone pour retirer la batterie pour réinitialiser le téléphone ... mais la batterie est toujours là).
PS L'une des nombreuses définitions de l'héritage que j'ai rencontrées: "Héritage - une technique de programmation qui permet à une classe dérivée d'étendre les fonctionnalités d'une classe de base, héritant de tous ses STATE (c'est moi qui souligne) et de son comportement."
Les champs privés, même s'ils ne sont pas accessibles par la sous-classe, sont l'état hérité de la superclasse.
la source
Je dois répondre que les champs privés de Java sont hérités. Permettez-moi de démontrer:
Si vous exécutez dans un programme
Bar bar = new Bar();
, vous verrez toujours le nombre "2" dans la boîte de sortie. Parce que l'entier "x" est encapsulé avec les méthodesupdate()
etgetX()
, alors il peut être prouvé que l'entier est hérité.La confusion est que parce que vous ne pouvez pas accéder directement à l'entier "x", les gens soutiennent qu'il n'est pas hérité. Cependant, chaque élément non statique d'une classe, que ce soit un champ ou une méthode, est hérité.
la source
Les bits de remplissage / alignement et l'inclusion de la classe d'objets dans la VTABLE ne sont pas pris en compte. L'objet de la sous-classe a donc une place pour les membres privés de la classe Super. Cependant, il n'est pas accessible à partir des objets de la sous-classe ...
la source
Non , les champs privés ne sont pas hérités. La seule raison est que la sous-classe ne peut pas y accéder directement .
la source
Je pense que la réponse dépend totalement de la question qui a été posée. Je veux dire, si la question est
Ensuite, la réponse est non , si nous passons par les détails du spécificateur d'accès , il est mentionné, les membres privés ne sont accessibles que dans la classe elle-même.
Mais, si la question est
Ce qui signifie, peu importe, ce que vous ferez pour accéder au membre privé. Dans ce cas, nous pouvons rendre la méthode publique dans la super-classe et vous pouvez accéder au membre privé. Donc, dans ce cas, vous créez une interface / un pont pour accéder au membre privé.
D'autres langages OOP comme C ++, ont le
friend function
concept, par lequel nous pouvons accéder au membre privé d'une autre classe.la source
Nous pouvons simplement déclarer que lorsqu'une superclasse est héritée, les membres privés de la superclasse deviennent en fait des membres privés de la sous-classe et ne peuvent plus être hérités ou sont inaccessibles aux objets de la sous-classe.
la source
Un membre de classe privée ou un constructeur n'est accessible que dans le corps de la classe de niveau supérieur ( §7.6 ) qui contient la déclaration du membre ou du constructeur. Il n'est pas hérité par les sous-classes. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
la source
Une sous-classe n'hérite pas des membres privés de sa classe parente. Cependant, si la superclasse a des méthodes publiques ou protégées pour accéder à ses champs privés, celles-ci peuvent également être utilisées par la sous-classe.
la source
Les membres privés (état et comportement) sont hérités. Ils peuvent (peuvent) affecter le comportement et la taille de l'objet qui est instancié par la classe. Sans oublier qu'ils sont très bien visibles pour les sous-classes via tous les mécanismes de rupture d'encapsulation qui sont disponibles, ou peuvent être assumés par leurs implémenteurs.
Bien que l'héritage ait une définition «de facto», il n'a certainement aucun lien avec les aspects de «visibilité», qui sont assumés par les réponses «non».
Il n'est donc pas nécessaire d'être diplomatique. JLS a tout simplement tort à ce stade.
Toute supposition selon laquelle ils ne sont pas "hérités" est dangereuse et dangereuse.
Ainsi, parmi deux définitions de facto (partiellement) contradictoires (que je ne répéterai pas), la seule qui devrait être suivie est celle qui est plus sûre (ou sûre).
la source