29 votes

Java: champ statique dans la classe abstraite

Je viens de commencer avec un exemple, qui l'explique le mieux:

public abstract class A{
    static String str;
}

public class B extends A{
    public B(){
        str = "123";
    }
}

public class C extends A{
    public C(){
        str = "abc";
    }
}

public class Main{

    public static void main(String[] args){
        A b = new B();
        A c = new C();
        System.out.println("b.str = " + b.str);
        System.out.println("c.str = " + c.str);
    }
}

Cela permettra d'imprimer:

b.str = abc

c.str = abc

Mais j'aimerais une solution où chaque sous-classe qui instancie la classe super, a sa propre variable de classe, en même temps, je veux être en mesure de renvoi que la classe de la variable par l'intermédiaire de l'identifiant, ou un appel de méthode, définie dans l'abstrait super classe.

Je voudrais donc la sortie:

b.str = 123

c.str = abc

C'est que c'est faisable?

37voto

Jon Skeet Points 692016

Si vous voulez que les classes B et C afin de séparer les variables statiques, vous aurez besoin de déclarer les variables dans ces classes. Fondamentalement, les membres statiques et le polymorphisme ne vont pas ensemble.

Notez que l'accès à des membres statiques par le biais de références est vraiment une mauvaise idée en termes de lisibilité - il fait regarder comme il dépend de la valeur de la référence, quand il n'est pas vraiment le cas. Si votre code ne sera même pas compiler lorsque vous avez déplacé str vers le bas pour B et C. au Lieu de cela, vous aurez besoin

System.out.println("b.str = " + B.str);
System.out.println("c.str = " + C.str);

Si vous avez vraiment besoin pour accéder à la valeur polymorphically (c'est à dire par une instance de A), puis une option est de faire un polymorphe de lecture:

public class A {
    public abstract String getStr();
}

public class B extends A {
    private static String str = "b";

    public String getStr() {
        return str;
    }
}

(et de même pour C).

De cette façon, vous obtenez le comportement que vous voulez en termes de ne pas avoir de séparer les variables par exemple, mais vous pouvez toujours l'utiliser polymorphically. C'est un peu bizarre pour un membre de l'instance de retourner une valeur statique comme ça, mais vous êtes à l'aide de la valeur pour le polymorphisme de type, essentiellement...

6voto

Bozho Points 273663
 public abstract class A {
    private String str;
    public String getStr() { return str;}
    protected void setStr(String str) { this.str = str; }
}
 

Ensuite, vous pourrez avoir

 B b = new B();
b.getStr();
 

Le setter et le getter sont mon ajout, vous pouvez simplement rendre la variable non statique.

Mise à jour Si vous souhaitez avoir la statique par sous-classe, vous pouvez avoir:

 protected static Map<Class, String> values;
public abstract String getValue();
 

puis:

 public String getValue() {
    values.get(getClass());
}
public void setValue(String value) {
    values.set(getClass(), value);
}
 

Mais c'est généralement une mauvaise idée.

2voto

Ralph Points 42744

Mettre la statique de la varibale dans chaque sous-classe, et ajouter une (non statique) résumé la méthode de la super-classe abstraite:

abstract String getStr();

Puis mettre en œuvre le getStr() dans chaque sous-classe, en retournant le champ statique de la présente sous-classe spéciale.

public class B extends A {
 private static String str;

  @Override
  public String getStr() {
    return B.str;
  }
}

2voto

Chirag Tayal Points 147

une seule instance de la variable statique est présent dans le système.

variable statique de charge dans le système dans le début avant la classe est chargé.

raison à la fois du temps abc est imprimé est parce que vous définissez la valeur de str comme abc dans la dernière.

2voto

Thijs Wouters Points 647

Cela permettra d'imprimer à la sortie que vous voulez:

public abstract class A{
}

public class B extends A{
    static String str;

    public B(){
        str = "123";
    }
}

public class C extends A{
    static String str;

    public C(){
        str = "abc";
    }
}

public class Main{

    public static void main(String[] args){
        A a = new B();
        A c = new C();
        System.out.println("B.str = " + B.str);
        System.out.println("C.str = " + C.str);
    }
}

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