2011-06-07 20 views

Respuesta

28

Si la clase InnerEvenIterator no se extiende a cualquier clase o implementación de la interfaz, creo que no tiene sentido porque no hay otra clase puede acceder a cualquier instancia de la misma.

Sin embargo, si extiende o implementa cualquier otra clase o interfaz no privada, tiene sentido. Un ejemplo:

interface EvenIterator { 
    public boolean hasNext(); 
} 


public class DataStructure { 
    // ... 

    private class InnerEvenIterator implements EvenIterator{ 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 

    InnerEvenIterator iterator; 

    public EvenIterator getIterator(){ 
     return iterator; 
    }  

} 
+0

Por lo tanto, como regla general, ningún modificador de acceso de miembro de clase puede tener prioridad sobre el modificador de acceso de la clase del miembro. ¿Es eso correcto? – jdurston

8

Es útil cuando se implementa ninguna interface.

class DataStructure implements Iterable<DataStructure> { 

    @Override 
    public Iterator<DataStructure> iterator() { 
     return new InnerEvenIterator(); 
    } 
    // ...   

    private class InnerEvenIterator implements Iterator<DataStructure> { 
     // ...  
     public boolean hasNext() { // Why public? 
      // ... 
      return false; 
     } 

     @Override 
     public DataStructure next() { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     @Override 
     public void remove() { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 
    } 

    public static void main(String[] ex) { 
     DataStructure ds = new DataStructure(); 
     Iterator<DataStructure> ids = ds.iterator(); 
     ids.hasNext(); // accessable    
    } 
} 
4

creo que se echa en falta la aplicación de la parte Iterator interfaz en su código de ejemplo. En ese caso, no puede hacer que el método hasNext() tenga otro identificador de visibilidad que no sea público, ya que eso reduciría su visibilidad (los métodos de interfaz tienen visibilidad pública) y no se compilará.

3

Existen muchas combinaciones de modificadores de acceso que no son útiles. Un método público en una clase interna privada solo es útil si implementa un método público en una clase/interfaz pública.

public class DataStructure { 
    // ... 

    private class InnerEvenIterator implements Iterator { 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 

    public Iterator iterator() { 
     return new InnerEvenIterator(); 
    } 
} 

Por cierto: las clases abstractas menudo tienen public constructores cuando en realidad son protected

+2

No se trata de ser "útil"; simplemente no tienes una opción cuando se trata de implementar una interfaz. :-) –

+1

Esto es cierto, pero mi punto es; si no está implementando o reemplazando un método público, el método no necesita ser público y podría tener ámbito privado para una clase privada. Hacerlo 'público' no es útil si no se puede acceder' public'ly y podría ser engañoso o confuso. –

12

Este método se puede hacer public con el fin de indicar que es semánticamente pública, a pesar del hecho de que el compilador no hace cumplir las reglas de visibilidad en este caso particular

Imagine que durante algunas refactorizaciones necesita hacer que este nivel superior de clase interna. Si este método es private, ¿cómo decidiría si se debería hacer public, o debería usarse algún modificador más restrictivo? El método de declaración como public le dice al lector las intenciones del autor original: este método no debe considerarse un detalle de implementación.

+4

¡Esto es exactamente cómo uso público y privado dentro de las clases anidadas! ¿Por qué escribiríamos las clases anidadas de una manera diferente utilizando métodos privados que se pueden llamar desde afuera? En general, creo que la clase externa no debe llamar a los métodos privados en la clase interna, solo a los métodos públicos, aunque el compilador no haga cumplir esto. Como beneficio adicional, posteriormente puede refactorizar la clase anidada a una clase de nivel superior sin tener que cambiar los métodos privados a públicos. –

1

Si la clase interna es privada, no se puede acceder por su nombre fuera de la clase externa. Las clases internas y externas tienen acceso a los métodos privados de cada uno y a las variables de instancia privadas. Mientras se encuentre dentro de la clase interna o externa, los modificadores públicos y privados tienen el mismo efecto. En el ejemplo de código:

public class DataStructure { 
    // ... 

    private class InnerEvenIterator { 
     // ... 

     public boolean hasNext() { // Why public? 
      // ... 
     } 
    } 
} 

En lo que respecta a la DataStructure clase, esto es completamente equivalente a:

public class DataStructure { 
    // ... 

    private class InnerEvenIterator { 
     // ... 

     private boolean hasNext() { 
      // ... 
     } 
    } 
} 

Esto es debido a que sólo DataStructure puede acceder a ella, por lo que no importa si lo configura para público o privado. De cualquier manera, DataStructure sigue siendo la única clase que puede acceder a ella. Utilice el modificador que desee, no hace ninguna diferencia funcional. La única vez que no puede elegir al azar es cuando está implementando o extendiendo, en cuyo caso no puede reducir el acceso, pero puede aumentarlo. Entonces, si un método abstracto tiene acceso protegido, puede cambiarlo a público. De acuerdo, ninguno de los dos hace ninguna diferencia.

Si planea usar una clase interna en otras clases y, por lo tanto, hacerla pública, probablemente no deba convertirla en una clase interna en primer lugar.

Además, no veo ningún requisito para que las clases internas amplíen o implementen otras clases. Puede ser común que lo hagan, pero ciertamente no es obligatorio.

+0

Existe una pequeña diferencia entre 'private' y' public' en este caso: los métodos no privados pueden ser anulados por otra clase interna mientras que los privados no. –

Cuestiones relacionadas