Mengapa variabel antarmuka statis dan final secara default di Java?
Mengapa variabel antarmuka statis dan final secara default di Java?
Jawaban:
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.
static
pengubah 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 interface
tidak dapat di-instantiated secara langsung - Anda masih dapat memiliki instance kelas yang mengimplementasikannya interface
dan masuk akal untuk mengharuskan mereka memiliki variabel instance publik tertentu. Adapun bagian tentang final
, itu tidak menawarkan penjelasan sama sekali - itu hanya menjelaskan apa final
artinya.
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 !!!
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.
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.
( Ini bukan jawaban filosofis tetapi lebih dari jawaban praktis ). Persyaratan untuk static
pengubah 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 interface
bidang 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 interface
properti tidak secara eksplisit menjadi final
oleh 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 Actionable
mengubah 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 NuclearAction
dapat 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 interface
akan menggunakan variabel-variabel ini, mereka harus secara implisit final
.
Karena hal lain adalah bagian dari implementasi, dan antarmuka tidak dapat memuat implementasi apa pun.
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.
static final
sebelum variabel yang sebenarnya statis dan final.
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
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
Antarmuka adalah kontrak antara dua pihak yang invarian, diukir di batu, karenanya final. Lihat Desain dengan Kontrak .
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.
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 final
yang berbeda dari variabel instan.
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.
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.
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));
}
}