Mengapa bisa't I menyatakan statis metode dalam interface?

Topik mengatakan sebagian besar dari itu - apa alasan untuk fakta bahwa metode statis dapat't dapat dinyatakan dalam sebuah antarmuka?

public interface ITest {
    public static String test();
}

Kode di atas memberi saya kesalahan berikut (dalam Eclipse, setidaknya): "Ilegal pengubah untuk antarmuka metode ITest.tes(); hanya publik & abstrak yang diizinkan".

Mengomentari pertanyaan (7)
Larutan

Ada beberapa persoalan yang bermain di sini. Pertama adalah isu yang menyatakan metode statis tanpa mendefinisikan itu. Ini adalah perbedaan antara

public interface Foo {
  public static int bar();
}

dan

public interface Foo {
  public static int bar() {
    ...
  }
}

Yang pertama adalah mustahil untuk alasan yang Espo menyebutkan: anda don't tahu yang melaksanakan kelas adalah definisi yang benar.

Jawa bisa memungkinkan terakhir; dan pada kenyataannya, mulai di Java 8, itu tidak!

Komentar (4)

Alasan mengapa anda dapat't memiliki metode statis dalam sebuah antarmuka yang terletak di jalan Jawa memecahkan statis referensi. Jawa tidak akan repot-repot mencari sebuah instance dari sebuah kelas ketika mencoba untuk menjalankan metode statis. Hal ini karena metode statis tidak contoh dependen dan karenanya dapat dieksekusi langsung dari file kelas. Mengingat bahwa semua metode dalam sebuah antarmuka yang abstrak, VM akan memiliki untuk mencari implementasi tertentu dari antarmuka dalam rangka untuk menemukan kode di balik metode statis sehingga bisa dieksekusi. Hal ini kemudian bertentangan bagaimana metode statis resolusi bekerja dan akan memperkenalkan sebuah inkonsistensi dalam bahasa.

Komentar (3)

I'll menjawab pertanyaan anda dengan sebuah contoh. Misalkan kita memiliki sebuah kelas Matematika dengan metode statis menambahkan. Anda akan memanggil metode ini seperti:

Math.add(2, 3);

Jika Matematika adalah sebuah antarmuka yang bukan dari kelas, ia tidak bisa memiliki fungsi yang ditetapkan. Seperti, mengatakan sesuatu seperti Matematika.tambahkan(2, 3) tidak masuk akal.

Komentar (0)

Alasannya terletak pada desain-prinsip, bahwa java tidak memungkinkan multiple inheritance. Masalah dengan multiple inheritance dapat diilustrasikan dengan contoh berikut:

public class A {
   public method x() {...}
}
public class B {
   public method x() {...}
}
public class C extends A, B { ... }

Sekarang apa yang terjadi jika anda menelepon C. x()? Akan A. x() atau B. x() dieksekusi? Setiap bahasa dengan beberapa warisan untuk memecahkan masalah ini.

Antarmuka memungkinkan di Jawa semacam dibatasi multiple inheritance. Untuk menghindari masalah di atas, mereka tidak diperbolehkan untuk memiliki metode. Jika kita melihat masalah yang sama dengan antarmuka dan metode statis:

public interface A {
   public static method x() {...}
}
public interface B {
   public static method x() {...}
}
public class C implements A, B { ... }

Masalah yang sama di sini, apa yang terjadi jika anda menelepon C. x()?

Komentar (7)

Metode statis tidak contoh metode. Ada's tidak ada contoh konteks, oleh karena itu untuk melaksanakan itu dari antarmuka yang masuk akal.

Komentar (0)

Sekarang Java8 memungkinkan kita untuk mendefinisikan bahkan Statis Metode dalam Interface.

interface X {
    static void foo() {
       System.out.println("foo");
    }
}

class Y implements X {
    //...
}

public class Z {
   public static void main(String[] args) {
      X.foo();
      // Y.foo(); // won't compile because foo() is a Static Method of X and not Y
   }
}

Catatan: Metode dalam Interface masih umum abstrak secara default jika kita don't secara eksplisit menggunakan kata kunci default/statis untuk membuat mereka Default metode Statis dan metode resp.

Komentar (0)

Ada's sangat bagus dan ringkas jawaban untuk pertanyaan anda di sini. (Itu memukul saya seperti baik cara mudah untuk menjelaskan hal itu yang ingin saya link dari sini.)

Komentar (1)

Tampaknya metode statis dalam antarmuka mungkin tidak didukung di Jawa 8, nah, solusi saya adalah hanya unggul mereka di dalam kelas.

interface Foo {
    // ...
    class fn {
        public static void func1(...) {
            // ...
        }
    }
}

Teknik yang sama juga dapat digunakan di anotasi:

public @interface Foo {
    String value();

    class fn {
        public static String getValue(Object obj) {
            Foo foo = obj.getClass().getAnnotation(Foo.class);
            return foo == null ? null : foo.value();
        }
    }
}

Dalam kelas harus selalu dapat diakses dalam bentuk Antarmuka.fn...bukanKelas.fn...`, maka, anda dapat menyingkirkan ambigu masalah.

Komentar (0)

Sebuah interface yang digunakan untuk polimorfisme, yang berlaku untuk benda-Benda, tidak jenis. Oleh karena itu (sebagaimana telah disebutkan) itu tidak masuk akal untuk memiliki antarmuka statis anggota.

Komentar (1)

Jawa 8 Telah mengubah dunia anda bisa memiliki metode statis dalam antarmuka tetapi memaksa anda untuk menyediakan implementasi untuk itu.

public interface StaticMethodInterface {
public static int testStaticMethod() {
    return 0;
}

/**
 * Illegal combination of modifiers for the interface method
 * testStaticMethod; only one of abstract, default, or static permitted
 * 
 * @param i
 * @return
 */
// public static abstract int testStaticMethod(float i);

default int testNonStaticMethod() {
    return 1;
}

/**
 * Without implementation.
 * 
 * @param i
 * @return
 */
int testNonStaticMethod(float i);

}

Komentar (0)

Sejak metode statis tidak dapat diwariskan . Jadi tidak ada gunanya menempatkan itu dalam antarmuka. Antarmuka pada dasarnya adalah kontrak yang semua pelanggan harus mengikuti . Menempatkan metode statis dalam antarmuka akan memaksa pelanggan untuk menerapkannya . yang sekarang menjadi kontradiktif dengan fakta bahwa metode statis tidak dapat diwariskan .

Komentar (1)

Ilegal kombinasi pengubah : statis dan abstrak

Jika ada anggota dari kelas ini dinyatakan sebagai statis, hal ini dapat digunakan dengan nama kelas yang terbatas pada kelas itu, tanpa menciptakan sebuah objek.

Jika ada anggota dari kelas yang dinyatakan abstract, anda perlu untuk menyatakan kelas abstrak dan anda perlu untuk menyediakan implementasi abstrak anggota untuk mewarisi class (Sub Class).

Anda perlu menyediakan sebuah implementasi ke abstrak anggota dari kelas sub-kelas di mana anda akan mengubah perilaku metode statis, juga dinyatakan sebagai abstrak yang terbatas untuk kelas dasar, yang tidak benar

Komentar (1)

Dengan Jawa 8, antarmuka sekarang dapat memiliki metode statis.

Misalnya, Komparator memiliki statis naturalOrder() metode.

Persyaratan yang interface tidak memiliki implementasi yang juga telah santai. Antarmuka sekarang dapat menyatakan "default" metode implementasi, yang seperti biasa implementasi dengan satu pengecualian: jika anda mewarisi kedua default implementasi dari sebuah interface dan normal implementasi dari sebuah superclass, yang superclass's pelaksanaannya akan selalu mengambil prioritas.

Komentar (3)

Mungkin contoh kode yang akan membantu, aku'm akan menggunakan C#, tapi anda harus bisa mengikuti.

Mari kita berpura-pura kami memiliki antarmuka yang disebut IPayable

public interface IPayable
{
    public Pay(double amount);
}

Sekarang, kami memiliki dua beton kelas yang mengimplementasikan interface ini:

public class BusinessAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

public class CustomerAccount : IPayable
{
    public void Pay(double amount)
    {
        //Logic
    }
}

Sekarang, mari kita berpura-pura kami memiliki koleksi berbagai akun, untuk melakukan hal ini kita akan menggunakan daftar generik jenis IPayable

List accountsToPay = new List();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());

Sekarang, kami ingin membayar $50.00 untuk semua akun tersebut:

foreach (IPayable account in accountsToPay)
{
    account.Pay(50.00);
}

Jadi sekarang anda melihat bagaimana antarmuka yang sangat berguna.

Mereka digunakan pada contoh benda-benda saja. Tidak statis kelas.

Jika anda telah membayar statis, ketika perulangan melalui IPayable's di accountsToPay tidak akan ada cara untuk mencari tahu apakah ia harus memanggil membayar BusinessAcount atau CustomerAccount.

Komentar (2)