wake-up-neo.com

Warum sind Schnittstellenvariablen standardmäßig statisch und final?

Warum sind Schnittstellenvariablen in Java standardmäßig statisch und final?

251
Jothi

Aus dem Java Interface Design FAQ von Philip Shaw:

Schnittstellenvariablen sind statisch, weil Java Schnittstellen nicht eigenständig instanziiert werden können; der Wert der Variablen muss in einem statischen Kontext zugewiesen werden, in dem keine Instanz existiert. Der letzte Modifikator stellt den zugewiesenen Wert sicher Die Schnittstellenvariable ist eine echte Konstante, die vom Programmcode nicht neu zugewiesen werden kann.

Quelle

250
cherouvim

Da die Schnittstelle kein direktes Objekt hat, können Sie nur mit einer Klasse/Schnittstelle darauf zugreifen. Wenn daher eine Schnittstellenvariable vorhanden ist, sollte sie statisch sein, da sie sonst für die Außenwelt überhaupt nicht zugänglich ist. Da es jetzt statisch ist, kann es nur einen Wert enthalten, und alle Klassen, die es implementieren, können es ändern, und daher wird alles durcheinander sein.

Wenn es also überhaupt eine Schnittstellenvariable gibt, ist sie implizit statisch, endgültig und offensichtlich öffentlich !!!

38
dganesh2002

public: für die Zugänglichkeit über alle Klassen hinweg, genau wie die in der Schnittstelle vorhandenen Methoden

statisch: da die Schnittstelle kein Objekt haben kann, kann die Variable interfaceName.variableName verwendet werden, um darauf zu verweisen, oder direkt die VariableName in der Klasse, die sie implementiert.

final: um sie zu Konstanten zu machen. Wenn 2 Klassen dieselbe Schnittstelle implementieren und Sie beiden das Recht geben, den Wert zu ändern, tritt ein Konflikt im aktuellen Wert der Variable auf, weshalb nur eine einmalige Initialisierung zulässig ist.

Außerdem sind all diese Modifikatoren für eine Schnittstelle implizit, sodass Sie keine von ihnen wirklich angeben müssen.

33
Nutan

(Dies ist keine philosophische, sondern eher eine praktische Antwort). Die Anforderung für den Modifikator static ist offensichtlich und wurde von anderen beantwortet. Da die Schnittstellen nicht instanziiert werden können, besteht die einzige Möglichkeit, auf ihre Felder zuzugreifen, darin, sie zu einem Klassenfeld zu machen - static.

Der Grund dafür, dass die interface -Felder automatisch zu final (Konstante) werden, besteht darin, zu verhindern, dass verschiedene Implementierungen versehentlich den Wert der Schnittstellenvariablen ändern, was sich versehentlich auf das Verhalten der anderen Implementierungen auswirken kann. Stellen Sie sich das folgende Szenario vor, in dem eine interface -Eigenschaft von Java nicht explizit zu final wurde:

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

Stellen Sie sich nun vor, was passieren würde, wenn eine andere Klasse, die Actionable implementiert, den Status der Schnittstellenvariablen ändert:

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

Wenn diese Klassen in einer einzelnen JVM von einem Klassenladeprogramm geladen werden, kann das Verhalten von NuclearAction von einer anderen Klasse, CleanAction, beeinflusst werden, wenn deren performAction() aufgerufen wird nachdem CleanAction 's ausgeführt wurde (im selben Thread oder auf andere Weise), was in diesem Fall katastrophal sein kann (semantisch gesehen).

Da wir nicht wissen, wie jede Implementierung eines interface diese Variablen verwenden wird, müssen sie implizit final sein.

12
Malvon

Weil alles andere Teil der Implementierung ist und Schnittstellen keine Implementierung enthalten können.

9
Amir Afghani

statisch - weil Interface keine Instanz haben kann. und schließlich - weil wir es nicht ändern müssen.

5
RubyDubee
public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

Hier ist die Lösung.

System.out.println(A.x); // done

Ich denke, es ist der einzige Grund, warum Schnittstellenvariablen statisch sind.

Deklarieren Sie keine Variablen innerhalb von Interface.

5
Asif Mushtaq

da:

Static: Da wir keine Objekte von Interfaces haben können, sollten wir die Verwendung von Membervariablen auf Objektebene vermeiden und Variablen auf Klassenebene verwenden, d. h. static.

Final: damit wir keine mehrdeutigen Werte für die Variablen haben (Diamond Problem - Multiple Inheritance).

Und gemäß der Dokumentationsschnittstelle handelt es sich um einen Vertrag und nicht um eine Implementierung.

referenz: Abhishek Jains Antwort auf Quora

3
Arun Raaj

Java erlaubt keine abstrakten Variablen und/oder Konstruktordefinitionen in Interfaces. Lösung: Hängen Sie einfach eine abstrakte Klasse zwischen Ihre Schnittstelle und Ihre Implementierung, die die abstrakte Klasse nur so erweitert:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

Sie können auch eine abstrakte Klasse ohne jede Schnittstelle verwenden, wenn Sie sicher sind, dass Sie sie später nicht zusammen mit anderen Schnittstellen implementieren möchten. Bitte beachten Sie, dass Sie keine Instanz einer abstrakten Klasse erstellen können, die Sie zuerst erweitern MÜSSEN.

(Das Schlüsselwort "protected" bedeutet, dass nur erweiterte Klassen auf diese Methoden und Variablen zugreifen können.)

spyro

2
spyro

Eine Schnittstelle ist ein Vertrag zwischen zwei Parteien, der unveränderlich, in den Stein gemeißelt und somit endgültig ist. Siehe Design by Contract .

1
Anssi

Stellen Sie sich eine Webanwendung vor, in der Sie eine Schnittstelle definiert haben und die von anderen Klassen implementiert wird. Da Sie keine Instanz der Schnittstelle für den Zugriff auf die Variablen erstellen können, benötigen Sie ein statisches Schlüsselwort. Jede Änderung des Werts wirkt sich seit seiner Statik auf andere Instanzen aus, die ihn implementiert haben. Um dies zu verhindern, definieren wir sie als endgültig.

0
srikant

Gerade in Eclipse ausprobiert, ist die Variable in der Schnittstelle standardmäßig final, sodass Sie sie nicht ändern können. Im Vergleich zur Elternklasse sind die Variablen definitiv änderbar. Warum? Aus meiner Sicht ist Variable in Klasse ein Attribut, das von Kindern geerbt wird, und Kinder können es entsprechend ihrem tatsächlichen Bedarf ändern. Im Gegenteil, die Schnittstelle definiert nur das Verhalten, nicht das Attribut. Der einzige Grund, Variablen in die Schnittstelle einzufügen, besteht darin, sie als Konstanten zu verwenden, die sich auf diese Schnittstelle beziehen. Dies ist jedoch keine gute Praxis, wie aus dem folgenden Auszug hervorgeht:

"Das Platzieren von Konstanten in einer Schnittstelle war in den Anfängen von Java eine beliebte Technik, aber heute wird sie von vielen als unangenehme Verwendung von Schnittstellen angesehen, da Schnittstellen die von einem Objekt bereitgestellten Dienste und nicht seine Daten behandeln sollten. Ebenso die verwendeten Konstanten von einer Klasse sind in der Regel ein Implementierungsdetail, aber das Platzieren in einer Schnittstelle befördert sie zur öffentlichen API der Klasse. "

Ich habe auch versucht, entweder statisch zu setzen oder es macht überhaupt keinen Unterschied. Der Code ist wie folgt:

public interface Addable {
    static int count = 6;

    public int add(int i);

}

public class Impl implements Addable {

    @Override
    public int add(int i) {
        return i+count;
    }
}

public class Test {

    public static void main(String... args) {
        Impl impl = new Impl();

        System.out.println(impl.add(4));
    }
}
0
muyong

In Java können Sie in der Schnittstelle keine Instanzvariablen deklarieren. Wenn Sie eine in einer Schnittstelle deklarierte Variable als Instanzvariable verwenden, wird ein Fehler bei der Kompilierung zurückgegeben.

Sie können eine konstante Variable mit static final Deklarieren, die sich von einer Instanzvariablen unterscheidet.

0
Giri

Die Schnittstelle kann von allen Klassen implementiert werden. Wenn dieser Wert von einer der implementierenden Klassen geändert wird, wird dies für andere implementierende Klassen irreführend. Interface ist im Grunde genommen eine Referenz, um zwei miteinander verbundene, aber unterschiedliche Entitäten zu kombinieren. Aus diesem Grund ist die deklarierende Variable innerhalb des Interfaces implizit endgültig und auch statisch, da das Interface nicht instanziiert werden kann.

0
user3889476