De ce't declar metode statice într-o interfață?

Subiectul spune că cea mai mare parte - care este motivul pentru faptul că metodele statice pot't fi declarat într-o interfață?

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

Codul de mai sus imi da urmatoarea eroare (în Eclipse, cel puțin): "Ilegală modificator pentru interfața metoda ITest.test(); public & abstract sunt permise".

Comentarii la întrebare (7)
Soluția

Există câteva probleme în joc aici. Prima este problema de a declara o metodă statică fără a defini aceasta. Aceasta este diferența între

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

și

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

Prima este imposibil pentru motive care Espo mentiuni: nu't știu ce de punere în aplicare clasă este definiția corectă.

Java ar putea permite acestuia din urmă; și, de fapt, începând din Java 8, nu-i!

Comentarii (4)

Motivul pentru care ai poate't au o metodă statică într-o interfață constă în modul Java rezolvă referințe statice. Java nu te va deranja în căutarea pentru o instanță a unei clase, atunci când încercarea de a executa o metodă statică. Acest lucru este pentru că metodele statice nu sunt dependente de exemplu și, prin urmare, pot fi executate direct din clasa file. Având în vedere că toate metodele din interfață sunt abstracte, VM-ar trebui să uite pentru un anumit punerea în aplicare a interfeței, în scopul de a găsi codul în spatele metodă statică astfel încât să poată fi executat. Acest lucru, atunci contrazice cum metodă statică de rezoluție funcționează și ar introduce o inconsecvență în limba.

Comentarii (3)

Am'll-ți răspund la întrebare printr-un exemplu. Să presupunem că vom avea o clasa de Matematica cu o metodă statică a adăuga. Te-ar suna această metodă astfel:

Math.add(2, 3);

Dacă Matematica a fost o interfață în loc de o clasă, aceasta nu ar putea avea nici funcții definite. Ca atare, spunând ceva de genul Matematica.adaugă(2, 3) nu are nici un sens.

Comentarii (0)

Motivul constă în design-principiu, ca java nu permite moștenire multiplă. Problema cu moștenire multiplă poate fi ilustrată prin următorul exemplu:

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

Acum ce se întâmplă dacă te sun C. x()? Va fi A. x() sau B. x() executat? Fiecare limbă cu moștenire multiplă trebuie să rezolve această problemă.

Interfețe permit în Java un fel de limitat moștenirea multiplă. Pentru a evita problema de mai sus, ei nu au voie să aibă metode. Dacă ne uităm la aceeași problemă cu interfețe și metode statice:

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

Aceeasi problema aici, ce se intampla daca suni C. x()?

Comentarii (7)

Metodele statice nu sunt exemplu de metode. Nu's nici un exemplu de context, prin urmare, să-l pună în aplicare de la interfața prea are sens.

Comentarii (0)

Acum Java8 ne permite să definim chiar Metode Statice în Interfață.

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

Notă: Metodele din Interfață sunt încă publice rezumat în mod implicit, dacă nu ne't în mod explicit utilizarea de cuvinte cheie default/static pentru a le face Implicit metode Statice și metode resp.

Comentarii (0)

Nu's un foarte frumos și concis răspunsul la întrebarea ta aici. (Mi s-a părut astfel un frumos simplu mod de a explica ce vreau să link-ul de aici.)

Comentarii (1)

Se pare că metoda statică în interfața ar putea fi sprijinite în Java 8, ei bine, soluția mea este doar de a le defini în clasa interior.

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

Aceeași tehnică poate fi de asemenea utilizat în adnotări:

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();
        }
    }
}

Clasa interior ar trebui să fie întotdeauna accesate în formă de Interfață.fn... "în loc de" Clasă.fn...`, apoi, puteți scăpa de ambiguu problema.

Comentarii (0)

O interfață este folosită pentru polimorfism, care se aplică la Obiecte, nu de tipuri. Prin urmare (după cum sa menționat deja) nu are nici un sens pentru a avea un statice interfață membru.

Comentarii (1)

Java 8-A schimbat lumea, puteți avea metode statice în interfață, dar forțele pentru a oferi în aplicare pentru asta.

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);

}

Comentarii (0)

Deoarece metodele statice nu pot fi moștenite . Deci nu folosi plasându-l în interfața. Interfața este practic un contract care toți abonații săi avea să urmeze . Introducerea o metodă statică în interfața va forța abonații să-l pună în aplicare . care acum devine contradictoriu la faptul că metodele statice nu pot fi moștenite .

Comentarii (1)

Ilegal combinație de modificatori : static și abstract

Dacă un membru al unei clase este declarat static, acesta poate fi folosit cu nume de clasă, care este limitat la clasa respectivă, fără a crea un obiect.

Dacă un membru al unei clase este declarat ca rezumat, trebuie să declare clasa ca abstract și aveți nevoie pentru a oferi punerea în aplicare a rezumat membru în moștenite de clasă (subclasă).

Ai nevoie de a oferi o punere în aplicare la abstract parte dintr-o clasă în sub-clasă în cazul în care aveți de gând pentru a schimba comportamentul de metodă statică, de asemenea, a declarat ca abstract care este limitat la clasa de baza, ceea ce nu este corect

Comentarii (1)

Cu Java 8, interfețele pot avea acum metode statice.

De exemplu, Comparator are un statice naturalOrder() metodă.

Cerința ca interfețe nu pot avea implementari a fost, de asemenea, relaxat. Interfețele pot declara acum "default" metodă de implementări, care sunt normali implementări cu o singură excepție: dacă ai moștenit atât o implementare implicită la o interfață și o normală punere în aplicare dintr-o superclasa, superclasa's aplicare va avea întotdeauna prioritate.

Comentarii (3)

Poate un exemplu de cod-ar ajuta, am'm de gând să utilizeze C#, dar ar trebui să fie capabil de a urmări de-a lungul.

Vă permite să pretindem că avem o interfață numită IPayable

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

Acum, avem două clase de beton care implementează această interfață:

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

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

Acum, să ne prefacem că avem o colecție de diverse conturi, pentru a face acest lucru, vom folosi o listă generică de tip IPayable

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

Acum, dorim să plătească $50.00 pentru toate aceste conturi:

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

Acum vezi cum interfețe sunt incredibil de util.

Ele sunt utilizate pe obiecte instanțiate numai. Nu pe clase statice.

Daca ati facut plata static, atunci când looping prin IPayable's în accountsToPay nu ar fi nici o cale de a afla dacă ar trebui să se solicite plata pe BusinessAcount sau CustomerAccount.

Comentarii (2)