4
votes

Dans Java 8, une méthode d'interface par défaut peut-elle accéder aux variables d'instance?

TL; TD Dans Java 8, existe-t-il un moyen pour une méthode d'interface par défaut d'accéder aux variables d'instance?

Par exemple:

public interface Foo{
    default getBazModified(){
       return baz * 2; 
    }
}

public class Bar implements Foo {
   int baz;
   ...
}

Je sais que cela ressemble à travisty mais y a-t-il un moyen de faire quelque chose comme ça dans Java 8?

Ou est-ce que le seul moyen est d'avoir une classe abstraite qui implémente Foo, qui aurait à la fois la variable d'instance baz em> déclaré et avoir une implémentation par défaut de getBazModified()?


4 commentaires

ressemble à un cas d'utilisation pour les arguments de méthode à implémenter


nullpointer, pouvez-vous préciser?


je veux dire un argument de méthode comme dans default int getBazModified (int baz) {return baz * 2; } , quel est le défi? puisque de toute façon vous appelez une méthode d'instance qui aurait sa propre valeur baz qu'elle peut transmettre lors de l'invocation de cette méthode.


stackoverflow.com/questions / 29666676 /…


3 Réponses :


1
votes

Avez-vous essayé de le compiler? La réponse est non car l’interface ne sait pas s’il y aura un champ nommé «baz» ou non.

Je sais que cela ressemble à du travesti, mais y a-t-il un moyen de faire quelque chose comme ça dans Java 8?

Oui. Une classe abstraite. C'est exactement ce pour quoi les classes abstraites ont été conçues.


1 commentaires

Je sais que cela ne compilerait pas, mais je demande si l'utilisation d'une classe fournissant l'implémentation par défaut est le seul moyen



10
votes

Une interface ne "voit" pas les champs d'instance de son implémentation. Ce n'est pas spécifique aux interfaces, aucun super-type ne connaîtrait les champs spécifiques de ses sous-types (ou n'importe quel type de membre d'ailleurs).

Votre solution dans ce cas est de déclarer une méthode getter abstraite dans le interface et utilisez-la pour lire la propriété de la sous-classe:

public class Bar implements Foo {
   int baz;
   public int getBaz() {return this.baz;}
}

Et laissez la classe concrète implémenter le getter:

public interface Foo{
    default int getBazModified(){
       return this.getBaz() * 2; 
    }

    int getBaz();
}

p>


2 commentaires

et tout cela dit, il doit y avoir un type de retour ( int ici) spécifié pour les méthodes


J'ai essayé d'obtenir un modèle correct et cette implémentation concrète pour le getter tout en le déclarant dans l'interface est parfaite. 10000%



3
votes

Non. Parce que les variables utilisées dans une méthode par défaut d'une interface n'ont accès qu'aux variables définies à l'intérieur de l'interface.

Foo foo = new Bar();
System.out.print(foo.getBazModified()); // output: 20 (access instance variable)

N'oubliez pas que les variables définies dans une interface sont publiques, statiques et définitives et doivent être initialisées.

Maintenant ,

public class Bar implements Foo {

  int BAZ = 10;

  @Override
  public int getBazModified() {
    return BAZ * 2;
  }
}

dans la classe d'appel ..

 Foo foo = new Bar();
 System.out.print(foo.getBazModified()); // output: 2

Vous ne pouvez accéder qu'à la variable d'instance à l'intérieur de la classe "Bar" en remplaçant la méthode par défaut. Comme ça,

public class Bar implements Foo {
  int BAZ = 10;
}

Et sachez si,

public interface Foo {
int BAZ=1;

default int getBazModified(){
    return BAZ * 2;
  }
}


0 commentaires