5 votes

Classe interne. Quel est son but ?

Quelqu'un peut-il me dire quel est l'intérêt d'avoir des classes internes? Je peux en imaginer quelques-unes mais peut-être ne sont-elles pas de bonnes raisons pour utiliser des classes internes. Mon raisonnement est que la classe interne est utile lorsque vous voulez utiliser une classe que aucune autre classe ne peut utiliser. Quoi d'autre?

3voto

Gavin H Points 6366

Lorsque j'apprenais Java, nous utilisions des classes internes pour les classes de gestion des événements GUI. C'est une sorte de classe "à usage unique" qui n'a pas besoin d'être disponible pour d'autres classes et qui n'est pertinente que pour la classe dans laquelle elle réside.

2voto

Bill Points 1556

J'utilise des classes internes pour définir une structure qui est mieux représentée par la classe contenant, mais ne nécessite pas nécessairement l'utilisation d'une classe externe séparée pour représenter la structure.

Pour donner un exemple, j'ai une classe qui représente un certain type de périphérique réseau, et la classe a certains types de tests qui peuvent être exécutés sur ce périphérique. Pour chaque test, il existe également un ensemble potentiel d'erreurs qui peuvent être trouvées. Chaque type de périphérique peut avoir une structure différente pour les erreurs.

Avec cela, vous pourriez faire des choses telles que

List errors = RemoteDeviceA.getErrors();

Avec des méthodes disponibles à partir de la classe interne, comme

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

Il existe bien sûr d'autres façons de faire cela, c'est simplement une approche de classe interne.

Code simplifié (aka incomplet) ci-dessus:

public class RemoteDeviceA {

    private String host;
    private String user;
    private String password;
    private static List errors;

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

        login();
    }

    private void login() {
        // Se connecte
    }

    public void runTestA() {

        List errorList = new ArrayList();

        // boucler à travers les résultats du test

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

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

    public List 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;
        }
    }
}

2voto

Pedro Rodrigues Points 1451

Les classes internes peuvent être utilisées pour simuler des fermetures: http://en.wikipedia.org/wiki/Closure_(computer_science)#Java

1voto

Will A Points 16763

Une implémentation de liste qui utilise internalement une liste chaînée pour stocker les éléments pourrait bien utiliser une classe interne pour représenter les nœuds à l'intérieur de la liste. Je pense que vous avez touché dans le mille en disant que vous utiliseriez une telle classe là où vous voulez l'utiliser internement à une classe mais ne voulez pas l'exposer - une classe "one off" qui n'est vraiment utile que "ici".

1voto

Jon Purdy Points 19408

J'utilise des classes internes (en C++) dans des situations où plusieurs classes, sans lien d'héritage, ont des détails d'implémentation conceptuellement similaires, qui forment une partie implicite de l'interface publique et devraient être nommés de manière similaire.

class lib::Identifier { ... };

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

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

Cela permet de se référer commodément à Identifier, Person::Identifier et File::Identifier simplement en tant que Identifier, dans les espaces de noms appropriés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X