2011-03-10 20 views
29

¿Hace la diferencia marcar métodos como public en clases de paquete privado?métodos públicos en clases privadas de paquete

class SomePackagePrivateClass 
{ 
    void foo();   // package private method 

    public void bar(); // public method 
} 

¿Hay alguna diferencia práctica en la visibilidad entre foo y bar aquí?

Respuesta

14

Si la clase no va a ser ampliado por otro, más visible subclase *, la única diferencia es claridad de intención. La declaración privada de todos los paquetes de métodos hace que sea más difícil para los lectores futuros determinar cuáles de los métodos deben llamar otras clases en el mismo paquete.

* que no tendría mucho sentido como una solución de diseño para mí, pero técnicamente es posible sin embargo.

+2

"Declarar todos los métodos como privados" debería leerse "Declarando todos los métodos package-private" y "la clase adjunta" como "otras clases", supongo, pero de lo contrario +1 – Puce

+0

@Puce, correcto, interpreté mal la pregunta. Ahora arreglado, gracias :-) –

4

Hace muy poca diferencia, a menos que la clase sea extendida por una clase pública (o anidada protegida).

Como una cuestión de consistencia, yo iría por public. Debería ser raro que los métodos no sean public o private.

Hay una serie de ejemplos de métodos públicos en el paquete privado java.lang.AbstractStringBuilder clase. Por ejemplo, length() es público en AbstractStringBuilder y está expuesto en la clase pública StringBuilder (anulado en StringBuffer para agregar sincronización).

+0

¿Tiene sentido extender una clase privada? – Deepak

+1

Extender un paquete de clase privada puede tener sentido, p.cuando la clase proporciona alguna base interna que es compartida por diferentes implementaciones en el paquete (hay algunos proyectos de código abierto que están haciendo esto). – Thomas

+0

'AbstractStringBuilder' (?) Se extiende por' StringBuffer' y 'StringBuilder' (está en los documentos de la API, pero probablemente sea un error/una mala característica en JavaDoc). –

-1

foo tiene default package visibility donde como bar tiene public visibilidad

+0

Pero 'bar' realmente no tiene visibilidad pública porque está en una clase que tiene acceso predeterminado (" paquete privado "). –

+0

'public void bar' el modificador utilizado aquí es público, así que supongo que tiene visibilidad pública.por favor corrígeme si estoy equivocado – Deepak

+0

' public void bar() 'tiene visibilidad pública, pero como Tom dijo, * prácticamente * no lo haces tener acceso público a la clase y, por lo tanto, no tener acceso público real al método (ya que ni siquiera se ve la clase). Sin embargo, cuando se trata de la herencia, las cosas se vuelven diferentes, tal como lo señaló Tom en su respuesta. – Thomas

35

Ejemplo utilizando la herencia:

A.java

package pkg1 

class A { 
    void foo(); 
    public void bar() {}; 
} 

B.java

package pkg1 

public class B extends A{ 

} 

C.java

package pkg2 

public class C { 
    public void doSomething() { 
    B b = new B(); 
    b.bar(); //ok 
    b.foo(); //won't work, since foo() is not visible outside of package 'pkg1' 

    A a = new A(); //won't work since A is not visible outside of package 'pkg1' 
    a.bar(); //won't work, since a cannot be created 
    } 
} 
8

Otro caso en el que el método tiene que ser público cuando está creando un paquete de implementación privada de alguna clase o interfaz pública. Como no tiene permitido reducir la visibilidad de los métodos anulados, estos deben ser públicos.

3

Bueno ... tuve esta duda también (es por eso que busqué este hilo). Esta podría ser una buena pregunta.

Pero ...

Después de un segundo pensamiento, las cosas son realmente más sencillo de lo que pensamos.

Un método de paquete privado, es un método de paquete privado.

¿Parece tonto? Pero ...

Un método paquete-privada, incluso si se hereda de su clase, es todavía un método paquete-privada.

¿Tiene más sentido ahora? Para una explicación más detallada:

Un método paquete-privada, incluso si su clase es heredada por una subclase más visible, es todavía un método paquete-privada.

Si la subclase es del mismo paquete, esos métodos privados del paquete también se heredan, pero todavía son paquetes privados.

Si la subclase es del paquete diferente (de aquí, necesitamos que la clase principal sea pública, con algunos métodos privados del paquete), los métodos privados del paquete son no heredados (porque no son visibles en absoluto)

Un punto a tener en cuenta, que puede ser la causa de esta duda, que un método de paquete privado en una clase pública no está visible fuera de su paquete también.


Lo anterior explica por el método de paquete-privada. Y el caso del método público es el mismo.

Cuando una clase de paquete-privada es heredada por una subclase del pubis (del mismo paquete, esto es una necesidad), sus métodos públicos se heredan como métodos públicos, y por lo tanto se convierten en métodos públicos de una clase púbico.

En el ejemplo OP, como foo() y bar() son ambos en una clase de paquete-privada, sus visibilidades se limitan a paquete-privada en este momento, hasta códigos adicionales se añaden (herencia por ejemplo).

Espero que esto sea claro (y simple) suficiente.

P.S. the Java access control table

2

Sí. Los métodos public en una clase package-private pueden ser útiles. Ejemplo ilustrativo de la biblioteca de Java (y tomado del clásico "java efectivo"):

¿Alguna vez ha visto el java.util.JumboEnumSet, java.util.RegularEnumSet ?? Probablemente no, porque son privados y no se mencionan en la documentación.

¿Alguna vez las ha usado? Probablemente si. Se devuelven mediante el método estático de java.util.EnumSet.noneOf(...). Aunque no puede construirlos usted mismo, puede usar sus métodos públicos cuando se devuelven desde este método.

Lo bueno de eso es que no sabes cuál estás usando, o incluso si existen. Java decide cuál es más eficiente dependiendo de los argumentos, y puede usar un diferente en una versión más nueva. Usted solo accede a su funcionalidad al referirse a ellos a través de su interfaz común (¡que es una buena práctica de todos modos!)

Cuestiones relacionadas