style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">

Modificadores de Acceso: private

Qué tal a todos,

Estoy repasando algunos apuntes de Java, y me han surgido algunas dudas específicamente para el modificador de acceso private. Según la teoría dice que los métodos private no se heredan sin embargo aquí tengo dos códigos que no llego a comprender del todo:

CODIGO 1 (Compila):

Archivo A.java:

class A extends B {
        public static void main( String[] args ) {
                A a = new A( );
                a.metodoPublic( );
        }
}

Archivo B.java:

class B {
       
        private void metodoPrivado( ) {
                System.out.println( "Hola privado" );
        }
       
                        public void metodoPublic( ) {
                metodoPrivado( );
        }
       
}

CODIGO 2 (No compila):

Archivo A.java:

class A extends B {
        public static void main( String[] args ) {
                A a = new A( );
                a.metodoPublic( );
        }

        public void metodoPublic( ) {
                metodoPrivado( );
        }
}

Archivo B.java:

class B {
       
        private void metodoPrivado( ) {
                System.out.println( "Hola privado" );
        }
       

}

Mi pregunta es: ¿Por qué compila el primer código y el segundo no compila? Tal vez sea algo muy sencillo, que a simple vista no logro notar, pero mi conciencia no está tranquila. Espero puedan ayudarme, gracias.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de benek

Modificadores de acceso.

En el primer caso el código compila y corre puesto que estás accediendo desde A al método público de B, y luego el método público de B accede al método privado de B. Recuerda que cuando es privado solo es visible dentro de la misma clase, y como es el método público de B quien lo llama si lo puede acceder. Cualquier método dentro de B podrá acceder a los métodos privados de esa misma clase.

En el segundo caso es diferente, estás intentando acceder el método privado directamente desde la clase A (sin entrar al método público de B como en el anterior caso), por lo cual lanza error en la compilación ya que A no puede acceder los métodos privados de B.

Postea de nuevo si no te quedó del todo claro.

PD. Recuerda introducir el código fuente que publiques en este sitio dentro de las etiquetas <code> y </code> para que tenga un mejor formato.

Javier Benek.
http://twitter.com/xbenek
http://www.javamexico.org/tema/lineamientos_de_publicacion

Re: Modificadores de Acceso: private

Un miembro privado (¿así se dice en Java?) sólo es accesible desde la misma clase en que fue declarado, esto descarta que las subclases tengan acceso a dichos miembros.

Saludos

Javier

Imagen de ezamudio

No existe

En tu caso es muy simple: la clase A no implementa metodoPrivado() por eso no compila.

Imagen de cfpmx

No me queda muy claro aún.

De hecho este ejemplo lo hice para intentar comprender el concepto de que los métodos privados no se heredan.

"En el primer caso el código compila y corre puesto que estás accediendo desde A al método público de B, y luego el método público de B accede al método privado de B. Recuerda que cuando es privado solo es visible dentro de la misma clase, y como es el método público de B quien lo llama si lo puede acceder. Cualquier método dentro de B podrá acceder a los métodos privados de esa misma clase."

En el primer código en la clase B tengo un método privado y un método público, luego en la clase A creo un OBJETO A, e intento acceder al método privado desde el método público y funciona, entontonces ahí surge mi duda ¿El método privado lo posee el objeto A?, es decir, entonces ¿ El objeto A heredó el método privado? Aquí es donde surge mis confusiones respecto a esto de los modificadores de acceso private en la herencia.

Imagen de cfpmx

No me queda muy claro aún.

"En tu caso es muy simple: la clase A no implementa metodoPrivado() por eso no compila."

Esa respuesta es con respecto al CODIGO 2. ¿Qué me puedes decir del CODIGO 1? Es decir, ¿el objeto A, heredó el método público y privado de la clase B? (ESTA ES LA RAZÓN DE SER DE ESTE POST, TENIENDO EN CUENTA QUE LOS PRIVATE NO SE HEREDAN, ENTONCES NO ME QUEDA CLARO POR QUÉ PUEDO HACER ESO)

Imagen de ezamudio

OK

ya revisé bien el código, no habia visto que la clase A heredaba de B, duh...

El código 1 corre porque el metodoPublic() está en B y ahí mismo está metodoPrivado(). El código 2 no corre porque el metodoPublic() está en A y el metodoPrivado() en B, y obviamente metodoPublic() no puede ver a metodoPrivado() porque los métodos private no son visibles a las subclases. Para eso tendrías que hacerlo protected.

La clase A no hereda metodoPrivado() porque es private.

Imagen de cfpmx

Re: OK

Bueno, tu respuesta creo poder tomarla como correcta simplemente CONFIANDO en tí. Pero la verdad todavía no me queda del todo claro, tomando en cuenta el concepto de herencia.

"El código 1 corre porque el metodoPublic() está en B y ahí mismo está metodoPrivado()."

Ok, los metodoPublic( ) y metodoPrivado( ) están en la clase B. Pero en el main creo un objeto de la clase A. Luego llamo a metodoPublic( ) que por ser público en B, luego A la hereda y desde ahí llama a metodoPrivado( ) y funciona correctamente, entonces ¿EL OBJETO DE LA CLASE A HEREDÓ EL metodoPrivado( ) DE LA CLASE B?

La teoría dice: "los métodos privados no se heredan", entonces por qué si creo un objeto de la clase A, puedo llamar al metodoPrivado( ) desde el metodoPublic( ), ¿acaso este lo heredó? De hecho, en CODIGO 1, no tendría dudas si en lugar de crear una objeto de la clase A, creara un objeto de la clase B, ya que así sería totalmente claro el concepto de herencia y métodos privados. Realmente mi duda se encuentra en el CODIGO 1... y CODIGO 2 sería una segunda observación.

Imagen de mathemathician

Hola

Muy buena pregunta la que haces. No es una pregunta de alguien que está aprendiendo. Pero bueno, la situación que planteas requiere de definiciones más precisas. Sobre todo del concepto de herencia. Voy a intentar una definicion más precisa de herencia. Primero: Una clase se compone de Atributos(variables) y Comportamientos (métodos) . Segundo: que una clase A herede de otra clase B significa que la clase A va a tener los atributos y comportamientos de la clase superior B, más atributos y comportamientos propios. Tercero: los atributos y comportamientos private no se heredan. Cuarto: si metodo() es un comportamiento no private de la clase B y la clase A hereda de B entonces metodo() también es un comportamiento de la clase A y un objeto de la clase A lo puede usar: Es decir: A a=new A(); a.metodo(); es válido sintácticamente. Si metodo() es un comportamiento private de la clase B entonces metodo() no es un comportamiento de la clase A y A a=new A(); a.metodo(); no es válido sintácticamente.
Las demás interpretaciones que haces no necesariamente significan herencia.

Imagen de cfpmx

Re: Hola

Que tal matemathician, gracias por tu respuesta, creo que ya he comprendido mi pequeña GRAN duda. El problema que tenía es que el concepto de herencia lo veía como un copiado y pegado de código que para este caso vendría siendo de la clase B, a la clase A que hereda de B, y al estar debatiendo con un compañero comprendí que mas que verlo como un copiado y pegado de código (imaginario), mas bien son cuestiones de visibilidad y alcance, es decir, el método público de B, es visto por A y es por esto que A puede ejecutar el método privado por medio del método público de B a través de A. En fin, creo que he logrado entender esto, después de un día de profunda intranquilidad y remordimiento de conciencia. Si estoy en lo incorrecto con lo que he mencionado, agradecería correcciones, por otro lado, si no estoy siendo muy claro y a alguien le interesa, me gustaría que me preguntara.

Y finalmente, tienes toda la razón, no estoy aprendiendo Java, mas bien estoy perfeccionando mis conocimientos, te comento que estoy preparándome para la certificación y pues entre los ejemplos rebuscados, me empecé hacer "bolas". Eres buen observador. Nos vemos, y una vez, gracias.

Herencia

CAFP-MX escribió:

La teoría dice: "los métodos privados no se heredan",

No lo dice la teoría, lo dicen Mathematician y The Java Language Specification (3rd edition).

Sección 6.6.1
"...if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor."

Sección 6.6.8
"A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses."

CAFP-MX escribió:

tu respuesta creo poder tomarla como correcta simplemente CONFIANDO en tí.

Uufff. Es un asunto técnico, así que la confianza es un valor agregado, pero no es indispensable. El tema es perfectamente explorable con las herramientas del JDK

$ cat test.java
class A extends B {
        public static void main( String[] args ) {
                A a = new A( );
                a.metodoPublic( );
        }
}

class B {

        private void metodoPrivado( ) {
                System.out.println( "Hola privado" );
        }

                        public void metodoPublic( ) {
                metodoPrivado( );
        }

}

$ javac test.java

$ javap -classpath . -private -c A
Compiled from "test.java"
class A extends B{
A();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method B."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   new     #2; //class A
   3:   dup
   4:   invokespecial   #3; //Method "<init>":()V
   7:   astore_1
   8:   aload_1
   9:   invokevirtual   #4; //Method metodoPublic:()V
   12:  return

}

$ javap -classpath . -private -c B
Compiled from "test.java"
class B extends java.lang.Object{
B();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

private void metodoPrivado();
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #3; //String Hola privado
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

public void metodoPublic();
  Code:
   0:   aload_0
   1:   invokespecial   #5; //Method metodoPrivado:()V
   4:   return

}

Debería estar más claro que una instancia de A no tiene de dónde llamar a metodoPrivado(), que existe sólo en B. Perfecciono mi primera aportación: "Un miembro o constructor privado sólo es accesible desde la misma clase en que fue declarado, esto descarta que las subclases tengan acceso a dichos miembros"

Saludos

Javier Castañón

Imagen de cfpmx

Que tal a todos, gracias por

Que tal a todos, gracias por sus respuestas, puedo dar este post por resuelto. Si alguien tiene dudas al respecto refiriéndome a personas con futuros problemas, no duden en contactárme para responderles, hasta luego.

style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-5164839828746352"
data-ad-slot="7563230308">