2010-08-02 20 views
5

¿Puede alguien decirme cuál es el propósito de tener clases internas? Puedo pensar en algunos, pero puede que no sean buenas razones para usar clases internas. Mi razonamiento es que la clase interna es útil cuando quieres usar una clase que ninguna otra clase puede usar. ¿Qué más?Clase interna. ¿Cual es su propósito?

+0

Tal vez para estructurar aún más el funcionamiento interno de una clase relativamente complejo sin exponerlos a la ¿público en general? ¿O para describir un tipo de datos complejo que solo tiene sentido dentro del contexto de la clase contenedora? – tdammers

Respuesta

1

Una implementación de lista que utiliza internamente una lista vinculada para almacenar los elementos podría hacer un buen uso de una clase interna para representar los nodos dentro de la lista. Creo que has dado en el clavo diciendo que utilizarías una clase de este tipo en la que quieras utilizarla internamente en una clase pero no la expongas, una clase "única" que solo es realmente útil 'aquí'.

3

Cuando estaba aprendiendo Java utilizamos clases internas para clases de manejo de eventos GUI. Es una especie de clase de "uso único" que no necesita estar disponible para otras clases, y solo es relevante para la clase en la que reside.

+0

Debe explicar ... específicamente, ¿cuáles son los peligros de * no * usar una clase interna en este caso? – Nitrodist

1

Utilizo las clases internas (en C++) en situaciones donde las clases múltiples, no relacionadas a través de la herencia, tienen detalles de implementación conceptualmente similares, que forman una parte implícita de la interfaz pública y deben nombrarse de manera similar.

class lib::Identifier { ... }; 

class lib::Person { 
public: 
    class Identifier : public lib::Identifier { ... }; 
}; 

class lib::File { 
public: 
    class Identifier : public lib::Identifier { ... }; 
}; 

Esto hace que sea conveniente para referirse a Identifier, Person::Identifier y File::Identifier simplemente como Identifier, en los ámbitos correspondientes.

2

Utilizo las clases internas para definir una estructura que está mejor representada por la clase contenedora, pero no necesariamente tiene sentido utilizar una clase externa separada para representar la estructura.

Para dar un ejemplo, tengo una clase que representa un tipo particular de dispositivo de red, y la clase tiene ciertos tipos de pruebas que se pueden ejecutar en ese dispositivo. Para cada prueba también hay un conjunto potencial de errores que se pueden encontrar. Cada tipo de dispositivo puede tener una estructura diferente para los errores.

Con esto se podría hacer cosas como

List<Error> errors = RemoteDeviceA.getErrors(); 

Con estar disponible desde la clase interna métodos, como

for (Error error : errors) { 
     System.out.println("MOnitor Type: " + error.getMonType()); 
     ... 
    } 

Por supuesto que hay otras maneras de hacer esto, esto es sólo un interior enfoque de clase

simplificado (aka incompleto) código de arriba:

public class RemoteDeviceA { 

    private String host; 
    private String user; 
    private String password; 
    private static List<Error> errors; 

    public RemoteDeviceA(String user, String host, String password) { 
     this.host = host; 
     this.user = user; 
     this.password = password; 

     login(); 
    } 

    private void login() { 
     // Logs in 
    } 

    public void runTestA() { 

     List<Error> errorList = new ArrayList<Error>(); 

     //loop through test results 

     if (!value.equals("0")) { 
      Error error = new Error(node, rackNum, shelfNum, slotNum, monType, value); 
      if (error.isError()) { 
       errorList.add(error); 
      } 
     } 
     setErrors(errorList); 
    } 

    private static void setErrors(List<Error> errors) { 
     RemoteDeviceA.errors = errors; 
    } 

    public List<Error> getErrors() { 
     return errors; 
    } 

    public class Error { 

     private String monType; 
     private String node; 
     private String rack; 
     private String shelf; 
     private String slot; 
     private String value; 
     private boolean error = false; 
     private boolean historyError = false; 
     private boolean critical = false; 
     private boolean criticalHistory = false; 

     Error(String node, String rack, String shelf, String slot, 
       String monType, String value) { 
      parseAlarm(node, rack, shelf, slot, monType, value); 
     } 

     private void parseAlarm(String node, String rack, String shelf, 
       String slot, String monType, String value) { 

      String modType = ""; 

      if (monType.startsWith("ES_15") && !value.equals("0")) { 
       setMonType("ES_15"); 
       setError(true); 
      } else if (monType.startsWith("SES_15") && !value.equals("0")) { 
       setMonType("SES_15"); 
       setError(true); 
      } else if (monType.startsWith("BBE_15") && !value.equals("0")) { 
       setMonType("BBE_15"); 
       setError(true); 
      } else if (monType.startsWith("UT_15") && !value.equals("0")) { 
       setMonType("UT_15"); 
       setError(true); 
       setCritial(critical); 
      } else if (monType.startsWith("ES_24") && !value.equals("0")) { 
       setMonType("ES_24"); 
       setHistoryError(true); 
       setError(true); 
      } else if (monType.startsWith("SES_24") && !value.equals("0")) { 
       setMonType("SES_24"); 
       setHistoryError(true); 
       setError(true); 
      } else if (monType.startsWith("BBE_24") && !value.equals("0")) { 
       setMonType("BBE_24"); 
       setHistoryError(true); 
       setError(true); 
      } else if (monType.startsWith("UT_24") && !value.equals("0")) { 
       setMonType("UT_24"); 
       setHistoryError(true); 
       setError(true); 
       setCriticalHistory(true); 
      } else if (monType.startsWith("UT_15") && !value.equals("0")) { 
       setMonType("UT_15"); 
       setError(true); 
       setCritial(true); 
      } else if (monType.startsWith("LASPWR")) { 

       float laserPwr = Float.valueOf(value); 

       if (node.startsWith("LEM_EM")) { 
        if ((laserPwr < 8.0) || (laserPwr > 12.0)) { 
         setMonType("LASERPWR"); 
         setError(true); 
        } 
       } else if (node.startsWith("LEM10")) { 
        if ((laserPwr < 18.0) || (laserPwr > 22.0)) { 
         setMonType("LASERPWR"); 
         setError(true); 
        } 
       } 
      } 

      if (isError()) { 
       setNode(node); 
       setRack(rack); 
       setShelf(shelf); 
       setSlot(slot); 
       setValue(value); 
       setError(true); 
      } 
     } 

     private void setMonType(String monType) { 
      this.monType = monType; 
     } 

     public String getMonType() { 
      return monType; 
     } 

     private void setNode(String node) { 
      this.node = node; 
     } 

     public String getNode() { 
      return node; 
     } 

     public void setRack(String rack) { 
      this.rack = rack; 
     } 

     public String getRack() { 
      return rack; 
     } 

     public void setShelf(String shelf) { 
      this.shelf = shelf; 
     } 

     public String getShelf() { 
      return shelf; 
     } 

     public void setSlot(String slot) { 
      this.slot = slot; 
     } 

     public String getSlot() { 
      return slot; 
     } 

     private void setValue(String value) { 
      this.value = value; 
     } 

     public String getValue() { 
      return value; 
     } 

     private void setError(boolean error) { 
      this.error = error; 
     } 

     public boolean isError() { 
      return error; 
     } 

     public void setCritial(boolean critical) { 
      this.critical = critical; 
     } 

     public boolean isCritical() { 
      return critical; 
     } 

     public void setCriticalHistory(boolean criticalHistory) { 
      this.criticalHistory = criticalHistory; 
     } 

     public boolean isCriticalHistory() { 
      return criticalHistory; 
     } 

     public void setHistoryError(boolean historyError) { 
      this.historyError = historyError; 
     } 

     public boolean isHistoryError() { 
      return historyError; 
     } 
    } 
}