Mengapa variabel antarmuka statis dan final secara default?

274

Mengapa variabel antarmuka statis dan final secara default di Java?

Jothi
sumber
41
Anda tidak harus meletakkan variabel apa pun di dalam Antarmuka.
cherouvim
34
Karena antarmuka mendefinisikan kontrak yang dapat diimplementasikan dengan berbagai cara. Nilai suatu variabel adalah implementasi.
cherouvim
10
Kita tentu bisa ketika kita tahu semua kelas yang mengimplementasikan antarmuka memiliki beberapa variabel konstan (Misalnya nama bidang).
Aniket Thakur
Apakah ide yang baik untuk membuat variabel di kelas sebagai instance dari antarmuka yang mengimplementasikan kelas? Saya pernah mendengar ini sebelumnya.
Doug Hauf
Antarmuka di java mengikuti prinsip ACID, final karena normalisasi dalam C. @cherouvim Jenis variabel adalah implementasi, variabel harus dideklarasikan, dengan atau tanpa nilai dan definisi variabel adalah nilai. Jika Anda mengubah nilai variabel tidak reimplementation, redefinisi.
Grim

Jawaban:

264

Dari FAQ desain antarmuka Java oleh Philip Shaw:

Variabel antarmuka bersifat statis karena antarmuka Java tidak dapat dipakai pada dirinya sendiri; nilai variabel harus ditetapkan dalam konteks statis di mana tidak ada instance. Pengubah akhir memastikan nilai yang ditetapkan untuk variabel antarmuka adalah konstanta yang benar yang tidak dapat ditugaskan kembali oleh kode program.

sumber

cherouvim
sumber
39
Perhatikan bahwa kelas abstrak tidak dapat dipakai "dalam hak mereka sendiri" baik dan mereka dapat memiliki variabel instan.
macias
18
Penjelasan untuk staticpengubah ini sepenuhnya palsu. Variabel instance publik kelas adalah bagian dari antarmuka dan tidak ada alasan mengapa mereka tidak boleh diabstraksi dalam Java interface, sama seperti metode instance. Tidak masalah bahwa Java interfacetidak dapat di-instantiated secara langsung - Anda masih dapat memiliki instance kelas yang mengimplementasikannya interfacedan masuk akal untuk mengharuskan mereka memiliki variabel instance publik tertentu. Adapun bagian tentang final, itu tidak menawarkan penjelasan sama sekali - itu hanya menjelaskan apa finalartinya.
pyrocrasty
3
Kutipan di atas lebih baik dalam konteks. Alasannya adalah "variabel antarmuka dimaksudkan untuk menjadi konstanta Java". Kutipan itu hanya menguraikan mengapa konstanta seperti itu statis dan final. Itu benar, tetapi pertanyaan sebenarnya adalah: mengapa variabel tidak diperbolehkan sebagai bagian dari antarmuka aktual (mis. Menentukan nama dan jenis anggota non-pribadi yang harus terjadi dalam kelas pelaksana). Jika mereka menginginkan "konstanta antarmuka" khusus, mereka dapat menggunakan sintaks baru, atau hanya memutuskan bahwa variabel apa pun yang sebenarnya didefinisikan dalam antarmuka adalah konstanta antarmuka.
pyrocrasty
6
Antarmuka tidak dapat memiliki variabel instan untuk menghindari pewarisan berganda masalah negara. Lihat docs.oracle.com/javase/tutorial/java/IandI/… . Kelas tidak dapat diperpanjang lebih dari satu kelas karena alasan yang sama.
denis
1
Bagaimana metode default diperkenalkan dan mereka memiliki instance, namun variabel instance tidak didukung ...
M.kazem Akhgary
41

Karena antarmuka tidak memiliki objek langsung, satu-satunya cara untuk mengaksesnya adalah dengan menggunakan kelas / antarmuka dan karenanya itulah mengapa jika variabel antarmuka ada, itu harus statis jika tidak dapat diakses sama sekali ke dunia luar. Sekarang karena ini statis, ia hanya dapat menampung satu nilai dan setiap kelas yang mengimplementasikannya dapat mengubahnya dan karenanya semuanya akan berantakan.

Oleh karena itu jika ada variabel antarmuka, itu akan secara implisit statis, final dan jelas bersifat publik !!!

dganesh2002
sumber
Tentu saja variabel instan akan dapat diakses jika diizinkan dalam Java interface. Kelas akan mengimplementasikan antarmuka, mendeklarasikan variabel instance (seperti yang dipersyaratkan oleh antarmuka). Konstruktornya (atau metode lain) menetapkan variabel instan. Ketika sebuah instance dari kelas dipakai, Anda akan dapat mengakses variabel instance-nya.
pyrocrasty
Java memungkinkan metode statis dengan tubuh ada di antarmuka. Mereka dapat mengakses variabel statis. Mereka tidak dapat mengubahnya, yang berarti fungsi statis tidak dapat menyimpan data apa pun
sederhana
36

publik : untuk aksesibilitas di semua kelas, sama seperti metode yang ada di antarmuka

statis : karena antarmuka tidak dapat memiliki objek, interfaceName.variableName dapat digunakan untuk referensi atau langsung variabelName di kelas yang mengimplementasikannya.

final : untuk menjadikannya konstanta. Jika 2 kelas mengimplementasikan antarmuka yang sama dan Anda memberi keduanya hak untuk mengubah nilai, konflik akan terjadi pada nilai saat ini dari var, itulah sebabnya mengapa hanya satu kali inisialisasi diizinkan.

Juga semua pengubah ini tersirat untuk antarmuka, Anda tidak perlu menentukan salah satu dari mereka.

Nutan
sumber
15

( Ini bukan jawaban filosofis tetapi lebih dari jawaban praktis ). Persyaratan untuk staticpengubah jelas yang telah dijawab oleh orang lain. Pada dasarnya, karena antarmuka tidak dapat dipakai, satu-satunya cara untuk mengakses bidangnya adalah menjadikannya bidang kelas - static.

Alasan di balik interfacebidang secara otomatis menjadi final(konstan) adalah untuk mencegah implementasi yang berbeda secara tidak sengaja mengubah nilai variabel antarmuka yang secara tidak sengaja dapat mempengaruhi perilaku implementasi lainnya. Bayangkan skenario di bawah ini di mana sebuah interfaceproperti tidak secara eksplisit menjadi finaloleh Java:

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!!!
        }
    }
}

Sekarang, coba pikirkan apa yang akan terjadi jika kelas lain yang mengimplementasikan Actionablemengubah keadaan variabel antarmuka:

public CleanAction implements Actionable  {

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

Jika kelas-kelas ini dimuat dalam JVM tunggal oleh classloader, maka perilaku NuclearActiondapat dipengaruhi oleh kelas lain CleanAction,, ketika performAction()dipanggil setelahCleanAction dieksekusi (di utas yang sama atau sebaliknya), yang dalam hal ini dapat menjadi bencana (semantik itu).

Karena kita tidak tahu bagaimana setiap implementasi interfaceakan menggunakan variabel-variabel ini, mereka harus secara implisit final.

Malvon
sumber
9

Karena hal lain adalah bagian dari implementasi, dan antarmuka tidak dapat memuat implementasi apa pun.

Amir Afghani
sumber
1
lalu apa alasan untuk final.
Jothi
7
Untuk menunjukkan bahwa ini adalah konstan. Java tidak memiliki kata kunci const. final statis adalah bagaimana Anda mendeklarasikan konstanta.
Amir Afghani
5
Karena Java 8, mereka dapat berisi implementasi, tetapi sangat disarankan untuk tidak menggunakannya jika Anda tidak memerlukan kompatibilitas backwarts. :)
codepleb
6
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?
    }
}

Ini solusinya.

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

Saya pikir itu adalah salah satu alasan mengapa variabel antarmuka statis.

Jangan mendeklarasikan variabel di dalam Antarmuka.

Asif Mushtaq
sumber
3
Bahkan, tanpa spesifikasi "Axe" bahkan tidak dapat dikompilasi ", sehingga sebenarnya aman untuk menggunakan variabel (yang secara implisit adalah final statis publik) dalam antarmuka.
Marco
Saya tidak setuju dengan jawabannya, seperti @Marco mengatakan itu bahkan tidak dapat dikompilasi. Saya tidak menemukan kelemahan lain sejauh ini, mungkin hanya karena Anda tidak melihat tulisan static finalsebelum variabel yang sebenarnya statis dan final.
Micer
5

statis - karena Antarmuka tidak dapat memiliki instance. dan final - karena kita tidak perlu mengubahnya.

RubyDubee
sumber
15
"kami tidak perlu" == "kami tidak diizinkan", jangan campur artinya.
peterh
3

karena:

Static : karena kita tidak dapat memiliki objek antarmuka sehingga kita harus menghindari menggunakan variabel anggota tingkat objek dan harus menggunakan variabel tingkat kelas yaitu statis.

Final : agar kita tidak memiliki nilai ambigu untuk variabel (masalah Diamond - Multiple Inheritance).

Dan sesuai antarmuka dokumentasi adalah kontrak dan bukan implementasi.

referensi: Jawaban Abhishek Jain tentang quora

Arun Raaj
sumber
2

Java tidak mengizinkan variabel abstrak dan / atau definisi konstruktor dalam antarmuka. Solusi: Cukup gantung kelas abstrak antara antarmuka Anda dan implementasi Anda yang hanya memperluas kelas abstrak seperti:

 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

 }

Anda juga dapat menggunakan kelas abstrak tanpa antarmuka apa pun jika Anda PASTI bahwa Anda tidak ingin mengimplementasikannya bersama dengan antarmuka lain nanti. Harap dicatat bahwa Anda tidak dapat membuat instance dari kelas abstrak yang Anda HARUS memperpanjangnya terlebih dahulu.

(Kata kunci "dilindungi" berarti bahwa hanya kelas yang diperluas yang dapat mengakses metode dan variabel ini.)

spyro

spyro
sumber
1

Antarmuka adalah kontrak antara dua pihak yang invarian, diukir di batu, karenanya final. Lihat Desain dengan Kontrak .

Anssi
sumber
1

Antarmuka: Layanan persyaratan sistem.

Dalam antarmuka, variabel secara default ditetapkan oleh publik, statis, pengubah akses akhir . Karena:

publik: Terjadi beberapa kali antarmuka mungkin ditempatkan di beberapa paket lain. Jadi itu perlu mengakses variabel dari mana saja di proyek.

statis: Karena kelas tidak lengkap seperti itu tidak dapat membuat objek. Jadi dalam proyek kita perlu mengakses variabel tanpa objek sehingga kita dapat mengakses dengan bantuaninterface_filename.variable_name

final: Misalkan satu antarmuka mengimplementasikan oleh banyak kelas dan semua kelas mencoba mengakses dan memperbarui variabel antarmuka. Jadi itu mengarah pada tidak konsistennya mengubah data dan mempengaruhi setiap kelas lainnya. Jadi perlu mendeklarasikan pengubah akses dengan final.

Vishal Sheth
sumber
0

Di Java , antarmuka tidak memungkinkan Anda untuk mendeklarasikan variabel instan apa pun. Menggunakan variabel yang dideklarasikan dalam antarmuka sebagai variabel instan akan mengembalikan kesalahan waktu kompilasi.

Anda bisa mendeklarasikan variabel konstan, menggunakan static finalyang berbeda dari variabel instan.

Giri
sumber
Ini jelas salah. Kompiler tidak akan mengeluh kecuali jika Anda membuatnya pribadi atau dilindungi. Di bawah tenda, seperti yang telah disebutkan orang lain, mereka dikonversi ke final statis publik. Dan saya kira itu sudah jelas mengapa. Karena antarmuka dimaksudkan untuk menentukan perilaku, bukan menyatakan.
Mikayil Abdullayev
0

Antarmuka dapat diimplementasikan oleh kelas apa saja dan bagaimana jika nilai itu diubah oleh salah satu kelas pelaksana di sana maka akan ada menyesatkan untuk kelas pelaksana lainnya. Antarmuka pada dasarnya adalah referensi untuk menggabungkan dua entitas yang saling berhubungan tetapi berbeda. Oleh karena itu, variabel yang mendeklarasikan di dalam antarmuka secara implisit bersifat final dan juga statis karena antarmuka tidak dapat dibuat instantiate.

pengguna3889476
sumber
0

Pikirkan aplikasi web tempat antarmuka Anda ditentukan dan kelas lain mengimplementasikannya. Karena Anda tidak dapat membuat instance antarmuka untuk mengakses variabel, Anda harus memiliki kata kunci statis. Karena sifatnya statis setiap perubahan nilai akan mencerminkan ke instance lain yang telah menerapkannya. Jadi untuk mencegahnya kita mendefinisikannya sebagai final.

srikant
sumber
0

Baru saja dicoba di Eclipse, variabel dalam antarmuka default menjadi final, jadi Anda tidak dapat mengubahnya. Dibandingkan dengan kelas induk, variabelnya pasti dapat diubah. Mengapa? Dari poin saya, variabel di kelas adalah atribut yang akan diwarisi oleh anak-anak, dan anak-anak dapat mengubahnya sesuai dengan kebutuhan mereka yang sebenarnya. Sebaliknya, antarmuka hanya mendefinisikan perilaku, bukan atribut. Satu-satunya alasan untuk memasukkan variabel dalam antarmuka adalah untuk menggunakannya sebagai const yang terkait dengan antarmuka itu. Padahal, ini bukan praktik yang baik menurut kutipan berikut:

"Menempatkan konstanta dalam antarmuka adalah teknik yang populer di masa-masa awal Jawa, tetapi sekarang banyak yang menganggapnya sebagai penggunaan antarmuka yang tidak menyenangkan, karena antarmuka harus berurusan dengan layanan yang disediakan oleh objek, bukan datanya. Juga, konstanta yang digunakan oleh sebuah kelas biasanya merupakan detail implementasi, tetapi menempatkannya di antarmuka mempromosikannya ke API publik dari kelas tersebut. "

Saya juga mencoba menempatkan statis atau tidak ada bedanya sama sekali. Kodenya seperti di bawah ini:

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));
    }
}
muyong
sumber