2010-08-10 4 views
3

J'ai une classe de base abstraite que de nombreuses classes étendent. Je souhaite que toutes ces classes définissent une valeur unique pour une propriété spécifique définie à l'origine dans la classe de base (similaire à la propriété serialVersionUID qui provoque un avertissement lorsqu'elle n'est pas définie dans les classes qui héritent de Serializable).Java: puis-je avoir besoin d'une classe enfant pour définir une valeur de propriété?

Existe-t-il un moyen pour moi, au sein de ma classe de base abstraite, de déclarer une propriété qui n'a pas de valeur, mais exige que toutes les classes étendues en définissent une valeur?

Notez que la valeur n'a pas à être associée à chaque instance individuelle, c'est-à-dire qu'elle peut être définie comme static.

Edit: je suppose une question plus fondamentale que je devrais aussi demander, puisque les réponses varient si largement, est comment Java mettre en œuvre serialVersionUID (en termes de signature) de telle sorte que mon IDE soulève des avertissements quand il est pas défini?

+2

'serialVersionUID' est juste un champ ordinaire que le mécanisme de sérialisation arrive à trouver (via l'introspection). Sa présence n'est pas imposée par le langage Java, ce qui explique pourquoi votre IDE émet un avertissement à ce sujet; Si la valeur était vraiment requise, ce serait une erreur obligatoire en cas d'absence. –

Répondre

2

Les champs ne peuvent pas être remplacés, mais les méthodes le peuvent. Si vous ne devez pas appliquer que la valeur est constante, utilisez:

class abstract Super() { 
    /** 
    * @return the magic value 
    */ 
    abstract MyType getValue(); 
} 

Si vous avez besoin de faire respecter que le champ est définitif, vous pouvez donner à chaque instance sa propre copie/référence dans les réponses de Steve ou Mike .

Si vous ne pouvez pas faire cela soit vous pouvez faire des choses folles comme:

class Super() { 
    private static Map<Class<? extends Super, MyType> map = new ...; 

    protected Super(MyType value) { 
     if (!map.contains(getClass())) { 
      map.put(getClass(), value); 
     } else { 
      assert map.get(getClass(), value) == value; 
     } 
    } 
} 
1

À peine. Je suggère de mettre des instructions d'utilisateur dans javadoc de votre classe de base et vérifier si la propriété est présente avant de l'utiliser: object.class.getDeclaredField("MY_CONSTANT")

Je pense que l'interface Serializable est un bon exemple d'une telle approche.

+0

Peut-être que la vérification de la présence du champ dans le super constructeur pourrait être appropriée. – meriton

1

reposter pour correspondre aux critères que je MANQUÉ:

public abstract class Abstract { 

    private static int field; 

    public Abstract(int aValue) { 
     field = aValue; 
    } 

    public int getField() { 
     return field; 
    } 
} 

public class Child extends Abstract { 

    private static final int value; 

    static { 
     value = 10; //Pick a value for each class. 
    } 

    public Child() { 
     super(value); 
    } 
} 
+0

C'est essentiellement ce que je suis en train de faire, sauf que mon constructeur 'Child()' ne prend aucun paramètre, appelant 'super()' avec la propriété 'aValue' définie dans l'appel à super lui-même. Cela ressemble plus à un bidouillage qu'à ce que je pense être d'autres possibilités, cependant. –

+0

Aussi bonne façon. Mais il dit qu'il a besoin d'une valeur par classe (pas d'objet), donc le constructeur _Child_ n'a pas vraiment besoin de paramètre. –

+0

Bon point. J'ai manqué ça, Nikkita. – Mike

0

Quelque chose comme ce qui suit est une approche typique de celle-ci:

public abstract class Superclass { 

    private final String something; 

    public Superclass(String something) { 
     this.something = something; 
    } 

    public String getSomething() { 
     return something; 
    } 
} 

public class Subclass { 

    public Subclass() { 
     super("a value for something"); 
    } 
} 

Vous ne recevez pas d'avoir une valeur de propriété statique bien.

Questions connexes