Esta es una pregunta de entrevista.
¿Las subclases heredan campos privados?
Respondí "No", porque no podemos acceder a ellos usando la "forma normal de OOP". Pero el entrevistador piensa que son heredados, porque podemos acceder a dichos campos indirectamente o usando la reflexión y todavía existen en el objeto.
Cuando regresé, encontré la siguiente cita en el javadoc :
Miembros privados en una superclase
Una subclase no hereda los miembros privados de su clase principal.
¿Conoces algún argumento para la opinión del entrevistador?
java
oop
inheritance
private
Stan Kurilin
fuente
fuente
Respuestas:
La mayor parte de la confusión en las preguntas / respuestas aquí rodea la definición de Herencia.
Obviamente, como @DigitalRoss explica que un OBJETO de una subclase debe contener los campos privados de su superclase. Como él dice, no tener acceso a un miembro privado no significa que no esté allí.
Sin embargo. Esto es diferente a la noción de herencia para una clase. Como es el caso en el mundo de Java, donde hay una cuestión de semántica, el árbitro es la Especificación del lenguaje Java (actualmente 3ª edición).
Como dice el JLS ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ):
Esto aborda la pregunta exacta planteada por el entrevistador: "las sub CLASAS heredan campos privados". (énfasis agregado por mí)
La respuesta es No. No lo hacen. Los OBJETOS de las subclases contienen campos privados de sus superclases. La subclase en sí NO tiene NOCIÓN de campos privados de su superclase.
¿Es la semántica de naturaleza pedante? Si. ¿Es una pregunta útil para la entrevista? Probablemente no. Pero el JLS establece la definición para el mundo Java, y lo hace (en este caso) sin ambigüedades.
EDITADO (eliminó una cita paralela de Bjarne Stroustrup que, debido a las diferencias entre java y c ++, probablemente solo aumente la confusión. Dejaré que mi respuesta descanse en el JLS :)
fuente
si
Es importante darse cuenta de que si bien no son dos clases, sólo hay un objeto.
Entonces, sí, por supuesto, heredó los campos privados. Son, presumiblemente, esenciales para la funcionalidad adecuada del objeto, y aunque un objeto de la clase padre no es un objeto de la clase derivada, una instancia de la clase derivada es definitivamente una instancia de la clase padre. No podría ser eso sin todos los campos.
No, no puedes acceder directamente a ellos. Sí, son heredados. Ellos tienen que ser.
Es una buena pregunta!
Actualizar:
Err, "No"
Bueno, supongo que todos aprendimos algo. Dado que el JLS originó la redacción exacta "no heredada", es correcto responder "no" . Dado que la subclase no puede acceder o modificar los campos privados, en otras palabras, no se heredan. Pero en realidad es simplemente un objeto, lo que realmente contiene los campos privados, y por lo que si alguien toma las JLS y redacción tutorial de la manera incorrecta, será bastante difícil de entender programación orientada a objetos, objetos Java, y lo que está sucediendo realmente.
Actualizar para actualizar:
La controversia aquí involucra una ambigüedad fundamental: ¿qué se está discutiendo exactamente? El objeto? ¿O estamos hablando en algún sentido sobre la clase misma? Se permite mucha latitud cuando se describe la clase en lugar del objeto. Por lo tanto, la subclase no hereda los campos privados, pero un objeto que es una instancia de la subclase ciertamente contiene los campos privados.
fuente
car
, lo mantuvo en unprivate
casillero del cual el niño no tiene la llave. De hecho, heredas elcar
pero es inútil para ti. Entonces, prácticamente, no te estás beneficiando con la herencia.No. Los campos privados no se heredan ... y por eso se inventó Protected . Es por diseño. Supongo que esto justificó la existencia de un modificador protegido.
Ahora llegando a los contextos. ¿Qué quiere decir con heredado, si está allí en el objeto creado a partir de la clase derivada? sí lo es.
Si quiere decir, ¿puede ser útil para la clase derivada? Bueno no.
Ahora, cuando se trata de la programación funcional, el campo privado de la superclase no se hereda de manera significativa para la subclase . Para la subclase, un campo privado de superclase es igual a un campo privado de cualquier otra clase.
Funcionalmente, no se hereda. Pero idealmente , lo es.
OK, acabo de ver el tutorial de Java que citan esto:
consulte: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
Estoy de acuerdo, que el campo está ahí. Pero, la subclase no obtiene ningún privilegio en ese campo privado. Para una subclase, el campo privado es el mismo que cualquier campo privado de cualquier otra clase.
Creo que es puramente una cuestión de punto de vista. Puede moldear el argumento a ambos lados. Es mejor justificar en ambos sentidos.
fuente
I believe it's purely matter of point-of-view.
yjustified the existence of protected modifier.
Depende de su definición de "heredar". ¿La subclase todavía tiene los campos en la memoria? Seguro. ¿Puede acceder a ellos directamente? No. Son solo sutilezas de la definición; El punto es entender lo que realmente está sucediendo.
fuente
Demostraré el concepto con código. Las subclases REALMENTE heredan las variables privadas de la superclase. El único problema es que no son accesibles para los objetos secundarios a menos que proporcione captadores y establecedores públicos para las variables privadas en la superclase.
Considere dos clases en el paquete Dump. El niño extiende a los padres.
Si no recuerdo mal, un objeto hijo en la memoria consta de dos regiones. Uno es solo la parte principal y el otro es solo la parte secundaria. Un niño puede acceder a la sección privada en el código de su padre solo a través de un método público en el padre.
Piénsalo de esta manera. El padre de Borat, Boltok, tiene una caja fuerte que contiene $ 100,000. No quiere compartir su caja fuerte variable "privada". Por lo tanto, no proporciona una clave para la caja fuerte. Borat hereda la caja fuerte. Pero, ¿de qué sirve si ni siquiera puede abrirlo? Si tan solo su padre hubiera proporcionado la llave.
Padre -
Niño -
fuente
No. No lo heredan.
El hecho de que alguna otra clase pueda usarlo indirectamente no dice nada sobre la herencia, sino sobre la encapsulación.
Por ejemplo:
También puede obtener el valor del
count
interior aUseIt
través de la reflexión. No significa, lo heredas.ACTUALIZAR
Aunque el valor está ahí, la subclase no lo hereda.
Por ejemplo, una subclase definida como:
Esta es exactamente la misma situación que el primer ejemplo. El atributo
count
está oculto y la subclase no lo hereda en absoluto. Aún así, como señala DigitalRoss, el valor está ahí, pero no por herencia.Ponlo de esta manera. Si tu padre es rico y te da una tarjeta de crédito, aún puedes comprar algo con su dinero, pero eso no significa que has heredado todo ese dinero, ¿verdad?
Otra actualización
Sin embargo, es muy interesante saber por qué el atributo está ahí.
Francamente, no tengo el término exacto para describirlo, pero es la JVM y la forma en que funciona que también carga la definición principal "no heredada".
Realmente podríamos cambiar el padre y la subclase seguirá funcionando.
Por ejemplo :
Creo que el término exacto se puede encontrar aquí: la especificación de máquina virtual JavaTM
fuente
encapsulation
vsinherit
, supongo que esta respuesta merece más votos.Bueno, mi respuesta a la pregunta del entrevistador es: los miembros privados no se heredan en las subclases, pero son accesibles para la subclase o el objeto de la subclase solo a través de métodos públicos de captación o establecimiento o cualquier método apropiado de la clase original. La práctica normal es mantener la privacidad de los miembros y acceder a ellos utilizando métodos getter y setter que son públicos. Entonces, ¿cuál es el punto de heredar solo los métodos getter y setter cuando el miembro privado con el que tratan no está disponible para el objeto? Aquí 'heredado' simplemente significa que está disponible directamente en la subclase para jugar con métodos recién introducidos en la subclase.
Guarde el archivo a continuación como ParentClass.java y pruébelo usted mismo ->
Si intentamos usar la variable privada x de ParentClass en el método de SubClass, entonces no se puede acceder directamente a ninguna modificación (significa no heredado). Pero x se puede modificar en SubClass a través del método setX () de la clase original como se hace en el método setXofParent () O se puede modificar usando el objeto ChildClass usando el método setX () o el método setXofParent () que finalmente llama a setX (). Así que aquí setX () y getX () son una especie de puertas para el miembro privado x de una ParentClass.
Otro ejemplo simple es que la superclase Clock tiene horas y minutos como miembros privados y los métodos getter y setter apropiados como públicos. Luego viene DigitalClock como una subclase de Clock. Aquí, si el objeto de DigitalClock no contiene horas y minutos miembros, entonces las cosas están jodidas.
fuente
Ok, este es un problema muy interesante. Investigué mucho y llegué a la conclusión de que los miembros privados de una superclase están realmente disponibles (pero no accesibles) en los objetos de la subclase. Para probar esto, aquí hay un código de muestra con una clase principal y una clase secundaria y estoy escribiendo un objeto de clase secundaria en un archivo txt y leyendo un miembro privado llamado 'bhavesh' en el archivo, demostrando que de hecho está disponible en el elemento secundario clase pero no accesible debido al modificador de acceso.
Abra MyData1.txt y busque el miembro privado llamado 'bhavesh'. Por favor díganme que piensan.
fuente
Parecería que una subclase hereda los campos privados en el sentido de que estos mismos campos se utilizan en el funcionamiento interno de la subclase (filosóficamente hablando). Una subclase, en su constructor, llama al constructor de la superclase. Los campos privados de la superclase obviamente son heredados por la subclase que llama al constructor de la superclase si el constructor de la superclase ha inicializado estos campos en su constructor. Eso es solo un ejemplo. Pero, por supuesto, sin métodos de acceso, la subclase no puede acceder a los campos privados de la superclase (es como no poder abrir el panel posterior de un iPhone para sacar la batería y reiniciar el teléfono ... pero la batería sigue ahí).
PD Una de las muchas definiciones de herencia que he encontrado: "Herencia: una técnica de programación que permite que una clase derivada extienda la funcionalidad de una clase base, heredando todo su ESTADO (el énfasis es mío) y su comportamiento".
Los campos privados, incluso si no son accesibles por la subclase, son el estado heredado de la superclase.
fuente
Tendría que responder que los campos privados en Java son heredados. Permítame demostrarle:
Si ejecuta un programa
Bar bar = new Bar();
, siempre verá el número "2" en el cuadro de salida. Debido a que el entero "x" se encapsula con los métodosupdate()
ygetX()
, entonces se puede demostrar que el entero se hereda.La confusión es que debido a que no se puede acceder directamente al número entero "x", la gente argumenta que no se hereda. Sin embargo, cada cosa no estática en una clase, ya sea campo o método, se hereda.
fuente
Los bits de relleno / alineación y la inclusión de la clase de objeto en el VTABLE no se considera. Entonces, el objeto de la subclase tiene un lugar para los miembros privados de la Superclase. Sin embargo, no se puede acceder desde los objetos de la subclase ...
fuente
No , los campos privados no se heredan. La única razón es que la subclase no puede acceder a ellos directamente .
fuente
Creo que la respuesta depende totalmente de la pregunta que se ha formulado. Quiero decir, si la pregunta es
Entonces la respuesta es No , si pasamos por los detalles del especificador de acceso , se menciona, los miembros privados solo son accesibles dentro de la clase misma.
Pero si la pregunta es
Lo que significa que no importa lo que hagas para acceder al miembro privado. En ese caso, podemos hacer un método público en la superclase y puede acceder al miembro privado. Entonces, en este caso, está creando una interfaz / puente para acceder al miembro privado.
Otros lenguajes OOP como C ++ tienen el
friend function
concepto, por el cual podemos acceder al miembro privado de otra clase.fuente
Simplemente podemos afirmar que cuando se hereda una superclase, los miembros privados de la superclase se convierten en miembros privados de la subclase y no pueden heredarse más o son inaccesibles para los objetos de la subclase.
fuente
Solo se puede acceder a un miembro o constructor de clase privada dentro del cuerpo de la clase de nivel superior ( §7.6 ) que encierra la declaración del miembro o constructor. No es heredado por las subclases. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
fuente
Una subclase no hereda los miembros privados de su clase principal. Sin embargo, si la superclase tiene métodos públicos o protegidos para acceder a sus campos privados, estos también pueden ser utilizados por la subclase.
fuente
Los miembros privados (estado y comportamiento) se heredan. Pueden (pueden) afectar el comportamiento y el tamaño del objeto que la clase crea. Sin mencionar que son muy visibles para las subclases a través de todos los mecanismos de ruptura de encapsulación que están disponibles o pueden ser asumidos por sus implementadores.
Aunque la herencia tiene una definición "de facto", definitivamente no tiene ningún vínculo con los aspectos de "visibilidad", que se asumen con las respuestas "no".
Entonces, no hay necesidad de ser diplomático. JLS está mal en este punto.
Cualquier suposición de que no son "heredados" es insegura y peligrosa.
Entonces, entre dos definiciones conflictivas de facto (parcialmente) (que no repetiré), la única que debe seguirse es la más segura (o segura).
fuente