8
votes

Comment utiliser des variables de membre avec des interfaces et des implémentations anonymes

Veuillez vérifier le code Java ci-dessous:

public class Test
{
  public static void main(String arg[]) throws Throwable
  {
      Test t = new Test();
      System.out.println(t.meth().s);           //OP: Old value
      System.out.println(t.meth().getVal());    //OP: String Implementation
  }
  private TestInter meth()
  {
    return new TestInter()
    {
      public String s = "String Implementation";
      public String getVal()
      {
        return this.s;
      }
    };
  }
}
interface TestInter
{
  String s = "Old value";
  String getVal();
}


0 commentaires

4 Réponses :


3
votes

Il n'y a rien de tel que Remplacement de la variable comme méthode primordial en java. Nommez un nouveau type pour Sous-classe , alors vous obtiendrez l'implémentation "String" , lorsque vous accédez au type de référence de sous-classe.

Accès privilège protégé < / Code> seulement signifie que nous pouvons accéder à la variable dans une sous-classe mais non qu'elle peut être remplacée.

même si vous utilisez la classe normale au lieu de interface Cela ne fonctionnera pas. Lorsque vous vous référez en utilisant le type de classe Super , vous obtenez uniquement l'instance à partir de Super Type et ainsi de suite .... Cet exemple illustre le premier cas: Exemple: xxx

Cet exemple illustre le deuxième cas: Il imprime "implémentation de chaîne" xxx


0 commentaires

1
votes
public String s = "String Implementation";

0 commentaires

7
votes

La variable S code> déclarée dans l'interface est entièrement séparé em> à partir de la variable S code> que vous avez déclaré dans votre classe intérieure anonyme.

Les variables d'interface sont vraiment conçues pour être des constantes - elles ne font pas partie de l'API à chaque mise en œuvre à fournir. En particulier, ils sont implicitement statiques et finaux. P>

de la Section JLS 9.3 : P>

Chaque déclaration de champ dans le corps d'une interface est implicitement publique, statique et finale. Il est permis de spécifier redondant tout ou tous ces modificateurs pour de tels champs. P> blockQquote>

Le fait que vous avez accédé au champ via une instance de mise en œuvre est hors de propos, ce code: p> xxx pré>

est efficacement: p>

t.meth();
System.out.println(TestInter.s);


3 commentaires

Vous auriez décourager l'utilisation ou recommander pour éviter les variables dans des interfaces, non?


@ Jonskeet mais même s'il étend une classe normale au lieu d'une interface, il obtient les mêmes résultats. Je l'ai testé. Suis-je correct, c'est ce que j'ai encadré dans ma réponse ... veuillez me corriger si je me trompe ... merci :)


@pinkpanther: Oui, vous obtenez les mêmes résultats, mais pour une raison légèrement différente. Vous avez absolument raison qu'il n'y ait pas de prime variable - il y aurait toujours deux variables différentes - mais c'est même pire avec la version d'interface car le champ est implicitement statique.



1
votes

Les champs déclarés dans une interface sont des constantes.

Ainsi, lors de l'écriture xxx

Vous déclarez une constante s. C'est pourquoi t.meth (). S est l'impression ancienne valeur

t.meth (). Getval () getval () Impression du contenu du champ s de votre classe anonyme.


0 commentaires