27 votes

Interfaces vs. énumérations

Entre interfaces et énumérations, lequel est le meilleur pour déclarer des constantes? Pourquoi est-ce le cas?

19voto

bragboy Points 13615

Il est toujours préférable d'utiliser des Enums pour déclarer des constantes car l'objectif des interfaces est sur un tout autre niveau. Oui, il y a beaucoup d'interfaces qui ont des constantes public static final, mais je pense que le rôle exclusif des enums est de vous fournir ces constantes.

11 votes

Les constantes public static final sont d'une époque antérieure aux enum. :)

6 votes

@Bombe, ce n'est pas tout à fait vrai. Si, par exemple, java.lang.Math devait être réécrit aujourd'hui, PI et E seraient toujours déclarés en tant que constantes public static final double.

9 votes

Oui, bien sûr, parce que la dernière fois que j'ai vérifié Math n'était pas une interface.

6voto

gustafc Points 13552

Si vos constantes doivent avoir un type spécifique pour une raison, si elles ont besoin d'un certain comportement (c'est-à-dire, des méthodes) ou si ce sont des composites d'autres valeurs, les enums sont la solution.

Par exemple, supposons que vous implémentiez un jeu de cartes et que vous vouliez représenter les valeurs et les enseignes :

enum Rank { 
    ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, 
    EIGHT, NINE, TEN, JACK, QUEEN, KING; 
}
enum Suit { SPADES, CLUBS, DIAMONDS, HEARTS } 

Il est maintenant impossible de créer des cartes avec des enseignes ou des valeurs invalides.

Cependant, parfois, vous êtes juste intéressé par un tas de valeurs fréquemment utilisées déclarées quelque part. Dans ce cas, les mettre dans un enum serait juste un effort inutile, puisque ces constantes ne sont qu'un outil pour nous éviter de mémoriser tous les décimales de, disons, π lorsque nous calculons la circonférence d'un cercle, ou quelque chose. Qu'est ce qui est mieux ?

// Utilisation de enum:
enum MathConstant { 
    PI(3.14159265358979323846), E(2.7182818284590452354);
    private final double value;
    MathConstant(double v) { value = v; }
    public double value() { return value; } 
}
// Usage:
double circonférence = MathConstant.PI.value() * diamètre;

// Utilisation d'une classe constante:
final class MathConstants { 
    private MathConstants() { throw new UnsupportedOperationException(); }
    public static final double PI = 3.14159265358979323846,
                               E = 2.7182818284590452354;
}
// Usage:
double circonférence = MathConstants.PI * diamètre;

Pour ce qui est des interfaces : Ne mettez jamais de constantes dans une interface. Le pattern "interface constante" est mauvais (justification), et le seul argument pour l'utiliser a été rendu caduc depuis l'ajout de import static à Java.

0 votes

L'interface publique HttpStatus d'Apache place des constantes dans une interface, ce que vous avez conseillé de ne pas faire. Par exemple - int SC_OK = 200; Les classes peuvent utiliser ces constantes en important statiquement HttpStatus. Est-ce que l'utilisation de l'interface ici pose toujours problème ?

2 votes

Eh bien, en quelque sorte. La principale raison contre les interfaces avec des constantes est que cela rend facile et confortable d'implémenter l'interface juste pour éviter d'avoir à importer les constantes. Il y a aussi des raisons sémantiques contre cela ; une interface est un ensemble de comportements qui peuvent être implémentés, pas un sac de constantes. Maintenant, les classes ne sont pas vraiment des endroits sémantiquement corrects pour placer des constantes non plus, mais elles peuvent être rendues finales et non instanciables, ce qui les fait se comporter davantage comme des sous-espaces de noms plutôt que des classes (ce que nous voulons).

5voto

twk Points 2220

Les interfaces sont conçues pour définir des comportements communs, les enums pour définir des valeurs communes.

L'enum représente une valeur réelle qui peut être comparée à une autre valeur, ou stockée dans la base de données facilement. Vous pouvez également avoir un drapeau-enum (en C#, je ne sais pas en Java) qui vous permet d'effectuer des opérations binaires sur les valeurs de l'enum (ET, OU, XOR, etc).

1 votes

En Java, les énumérations sont essentiellement des classes (constants), ainsi vous pouvez faire beaucoup plus avec eux qu'avec les énumérations en c# avant .net 4.0. Je pense que C# / .net 4.0 va implémenter cette fonctionnalité.

0 votes

@Tedil: L'ensemble des fonctionnalités de C# 4.0 a été finalisé. Cela n'inclut pas les énumérations OO améliorées.

0voto

Horcrux7 Points 8369

Si vous travaillez avec Java 5 ou une version plus récente, alors les Enum sont la voie à suivre. La seule exception est si votre liste de const est ouverte et peut être étendue. Les énumérations ne peuvent pas être étendues. Une autre exception est si ce sont des valeurs uniques comme un MAX_INTEGER.

0voto

Arezki Points 1

Juste un code :

public interface InterfaceForConstants() {
    String **TOTO** = "Et voilà !";
    double **PI** = 3.14159265358979323846;
}

En utilisant :

class ClasseName implements InterfaceForConstants () {

    String myString;

    if (myString.equals(**TOTO**) {
        // faire quelque chose
    }

    double circonférence = **PI** * diamètre; // au lieu de MathConstants.PI * diamètre;

}

Propre et simple. Si quelque chose peut faire ce dont vous avez besoin, prenez la solution la plus simple ! Écrire du code selon les règles est bien, écrire du code facile à lire est mieux, même si une règle n'est pas respectée. Pensez à quand vous devrez relire votre code après quelques mois. Si vous voulez être plus précis, faites une javadoc pour l'expliquer !

1 votes

C'est pas propre, c'est horrible

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