it-swarm.dev

Java arayüzünde neden statik bir metot tanımlayamıyorum?

EDIT: Java 8'den itibaren, arayüzlerde statik yöntemlere artık izin verilmektedir.

İşte örnek:

public interface IXMLizable<T>
{
  static T newInstanceFromXML(Element e);
  Element toXMLElement();
}

Tabii bu işe yaramaz. Ama neden olmasın?

Muhtemel sorunlardan biri, aradığınızda ne olacağı olacaktır:

IXMLizable.newInstanceFromXML(e);

Bu durumda, bence sadece boş bir yöntem (yani {}) çağırmalıdır. Tüm alt sınıflar statik yöntemi uygulamak zorunda kalacaktı, bu yüzden statik yöntemi çağırırken hepsi iyi olacaktı. Peki neden bu mümkün değil?

EDIT: Sanırım "çünkü bu şekilde Java" dan daha derin bir cevap arıyorum.

Statik yöntemlerin üzerine yazılamamasının belirli bir teknolojik sebebi var mı? Bu nedenle, neden Java tasarımcıları örnek yöntemleri geçersiz kılmaya ama statik yöntemler olarak kullanmaya karar verdi?

EDIT: Tasarımımdaki sorun kodlama kurallarını uygulamak için arayüzleri kullanmaya çalışıyorum.

Yani, arayüzün amacı iki yönlüdür:

  1. IXMLizable arabiriminin onu uygulayan sınıfları XML öğelerine dönüştürmeme izin vermesini istiyorum (polimorfizm kullanarak, iyi çalışıyor).

  2. Birisi IXMLizable arayüzünü uygulayan bir sınıfın yeni bir örneğini yapmak isterse, her zaman bir newInstanceFromXML (Element e) statik yapıcısı olacağını bilir.

Bunu sağlamanın, arayüze yorum yapmaktan başka bir yolu var mı?

465
cdmckay

Java 8 statik arayüz yöntemlerine izin verir

Java 8 ile, arayüzler statik yöntemlere sahip olabilir. Ayrıca somut örnek yöntemlere sahip olabilirler ancak örnek alanlara sahip olamazlar.

Burada gerçekten iki soru var:

  1. Neden kötü eski günlerde, arayüzler statik yöntemler içeremez?
  2. Statik yöntemler neden geçersiz kılınmıyor?

Arayüzeylerde statik yöntemler

Önceki sürümlerde arayüzlerin statik yöntemlere sahip olmamasının güçlü bir teknik sebebi yoktu. Bu , posterin güzelce özetlediği yinelenen bir sorunun cevabıdır. Statik arayüz yöntemleri başlangıçta küçük bir dil değişikliği, ve Java 7'ye eklemek için resmi bir teklif olarak kabul edildi. ancak daha sonra oldu öngörülemeyen komplikasyonlar nedeniyle düştü.

Son olarak, Java 8, statik bir uygulama yönteminin yanı sıra varsayılan bir uygulamayla geçersiz kılınabilen örnek yöntemlerini tanıttı. Yine de örnek alanlara sahip olamazlar. Bu özellikler lambda ifade desteğinin bir parçasıdır ve bunlar hakkında daha fazla bilgiyi JSR 335'in H Bölümü).

Statik yöntemleri geçersiz kılma

İkinci sorunun cevabı biraz daha karmaşık.

Statik yöntemler derleme zamanında çözülebilir. Dinamik gönderim, örneğin derleyicinin nesnenin somut türünü belirleyemediği ve dolayısıyla çağrılacak yöntemi çözemediği yöntemler için anlamlıdır. Ancak statik bir yöntemi çağırmak bir sınıf gerektirir ve o sınıf bilindiğinden beri statik olarak - derleme zamanında — dinamik gönderim gerekli değildir.

Burada neler olup bittiğini anlamak için örnek yöntemlerin nasıl çalıştığına dair küçük bir arka plan gereklidir. Gerçek uygulamanın oldukça farklı olduğundan eminim, ancak davranışları doğru bir şekilde gözlemleyen modelleri belirleyen metod gönderme fikrimi açıklamama izin verin.

Her sınıfın, yöntemi uygulamak için gerçek bir kod öbeğine yöntem imzalarını (ad ve parametre türleri) eşleyen bir karma tabloya sahip olduğunu farz edin. Sanal makine bir örnek için bir yöntem çağırmaya çalıştığında, nesnesini sınıfını sorgular ve istenen imzayı sınıfın tablosunda arar. Bir yöntem gövdesi bulunursa, çağrılır. Aksi takdirde, sınıfın ana sınıfı elde edilir ve arama burada tekrarlanır. Bu, yöntem bulunana kadar devam eder veya daha fazla üst sınıf yoktur; bu NoSuchMethodError ile sonuçlanır.

Bir üst sınıf ve bir alt sınıf aynı yöntem imzası için tablolarında bir girişe sahipse, önce alt sınıfın sürümüyle karşılaşılır ve üst sınıfın sürümü hiçbir zaman kullanılmaz - bu bir "geçersiz kılma" dır.

Şimdi, nesne örneğini atladığımızı ve sadece bir alt sınıfla başladığımızı varsayalım. Çözünürlük yukarıdaki gibi devam edebilir ve size bir çeşit "geçersiz kılınabilir" statik yöntem verir. Bununla birlikte, çözümlemenin tümü derleme zamanında gerçekleşebilir, çünkü derleyici, sınıfı için belirtilmemiş bir türdeki bir nesneyi sorgulamak için çalışma zamanını beklemek yerine bilinen bir sınıftan başlamaktadır. İstenilen sürümü içeren sınıfı her zaman belirleyebileceğinden statik bir yöntemin "geçersiz kılmasında" hiçbir anlamı yoktur.


Yapıcı "arayüzler"

İşte soruya yapılan son düzenlemeyi ele almak için biraz daha malzeme.

IXMLizable öğesinin her uygulaması için etkin bir şekilde yapıcı benzeri bir yöntem uygulamak istediğiniz gibi görünüyor. Bunu bir dakika boyunca bir arayüzle zorlamaya çalışmayı unutun ve bu gereksinimi karşılayan bazı sınıflarınız varmış gibi yapın. Nasıl kullanırsın?

class Foo implements IXMLizable<Foo> {
  public static Foo newInstanceFromXML(Element e) { ... }
}

Foo obj = Foo.newInstanceFromXML(e);

Yeni nesneyi "oluştururken" açıkça somut türünü Foo olarak adlandırmanız gerektiğinden, derleyici gerçekten gerekli fabrika yöntemine sahip olduğunu doğrulayabilir. Ve değilse, ne olmuş? Eğer "constructor" 'a sahip olmayan bir IXMLizable uygulayabilirsem ve bir örnek oluşturup kodunuza geçirirsem, bir IXMLizable olur. gerekli arayüz.

İnşaat, uygulamanın bir parçasıdır, arayüz değildir. Arayüzle başarılı bir şekilde çalışan herhangi bir kod, yapıcıyı önemsemez. Yapıcıyı önemseyen herhangi bir kodun zaten beton tipini bilmesi gerekir ve arabirim yoksayılabilir.

490
erickson

Bu zaten istendi ve cevaplandı, burada

Cevabımı çoğaltmak için:

Arayüzde statik bir yöntem bildirmenin bir anlamı yoktur. MyInterface.staticMethod () normal çağrısı tarafından yürütülemezler. Onları uygulayıcı sınıf MyImplementor.staticMethod () belirterek çağırırsanız, o zaman asıl sınıfı bilmeniz gerekir, bu nedenle arayüzün içerip içermemesi önemsizdir.

Daha da önemlisi, statik yöntemler asla geçersiz kılınır ve bunu yapmaya çalışırsanız:

MyInterface var = new MyImplementingClass();
var.staticMethod();

statik kuralları, beyan edilen var türünde tanımlanan yöntemin çalıştırılması gerektiğini söyler. Bu bir arayüz olduğu için bu imkansız.

"Result = MyInterface.staticMethod ()" komutunu çalıştıramadığınızın nedeni, MyInterface'te tanımlanan yöntemin sürümünü çalıştırmak zorunda kalmasıdır. Ancak MyInterface'te tanımlanan bir sürüm olamaz, çünkü bu bir arayüzdür. Tanımı gereği kod yoktur.

Bunun "Java böyle yaptığı için" anlamına geldiğini söylese de, gerçekte karar, diğer tasarım kararlarının mantıklı bir sonucudur, aynı zamanda çok iyi bir sebepten de alınmaktadır.

46
DJClayworth

Normalde bu bir Fabrika modeli kullanılarak yapılır.

public interface IXMLizableFactory<T extends IXMLizable> {
  public T newInstanceFromXML(Element e);
}

public interface IXMLizable {
  public Element toXMLElement();
}
36
Peter Lawrey

Java 8'in çıkışıyla varsayılan varsayılan ve Arayüzde statik yöntemleri. docs.Oracle/staticMethod

Örneğin:

public interface Arithmetic {

    public int add(int a, int b);

    public static int multiply(int a, int b) {
        return a * b;
    }
}
public class ArithmaticImplementation implements Arithmetic {

    @Override
    public int add(int a, int b) {
        return a + b;
    }

    public static void main(String[] args) {
        int result = Arithmetic.multiply(2, 3);
        System.out.println(result);
    }
}

Sonuç : 6

İPUCU: Statik bir arabirim yöntemi çağırmak, herhangi bir sınıf tarafından gerçekleştirilmek zorunda değildir. Elbette, bunun nedeni, üst sınıflardaki statik yöntemler için aynı kuralların, arabirimlerdeki statik yöntemler için geçerli olmasıdır.

33
rogue lad

Çünkü statik yöntemler alt sınıflarda geçersiz kılınamaz ve bu nedenle soyut olamazlar. Ve bir arayüzdeki tüm yöntemler, de facto, abstract.

19
Michael Myers

Java arayüzünde neden statik bir metot tanımlayamıyorum?

Aslında Java 8’de yapabilirsiniz.

Java'ya göre doc :

Statik yöntem, tanımlandığı sınıfla, herhangi bir nesneyle değil, ilişkili bir yöntemdir. Sınıfın her örneği statik yöntemlerini paylaşıyor

Java 8'de bir arayüz varsayılan yöntemlere ve statik yöntemlere sahip olabilir. Bu, kütüphanelerimizde yardımcı yöntemler düzenlememizi kolaylaştırır. Arayüze özgü statik yöntemleri, ayrı bir sınıftan ziyade aynı arayüzde tutabiliriz.

Varsayılan yöntem örneği:

list.sort(ordering);

yerine

Collections.sort(list, ordering);

Statik yöntem örneği ( doc öğesinin kendisinden):

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}
10
i_am_zero

İlk olarak, tüm dil kararları dil yaratıcıları tarafından verilen kararlardır. Statik bir yöntemin bir arayüzün parçası olamayacağını söyleyen yazılım mühendisliği veya dil tanımlayan veya derleyici/tercüman yazma dünyasında hiçbir şey yoktur. Birkaç dil yarattım ve onlar için derleyiciler yazdım - hepsi oturmuş ve anlamlı bir anlam ifade ediyor. Bir arabirimdeki statik bir yöntemin anlambiliminin, derleyici çalışma zamanına göre yöntemin çözünürlüğünü ertelemek zorunda olsa bile, oldukça açık olduğunu savunuyorum.

İkincisi, statik yöntemleri kullandığımız anlamına gelir ki, statik yöntemler içeren bir arabirim modeline sahip olmak için geçerli bir neden vardır - Herhangi biriniz için konuşamam, ancak düzenli olarak statik yöntemler kullanırım.

En muhtemel doğru cevap, dil tanımlandığı zaman, arayüzlerdeki statik yöntemler için algılanan bir ihtiyaç olmadığıdır. Java yıllar içinde çok büyüdü ve bu görünüşe göre ilgi çeken bir şey. Java 7'ye bakılmasının dil değişikliğine yol açabilecek bir ilgi seviyesine yükseldiğini gösterir. Birincisi, artık bir nesneyi somutlaştırmak zorunda olmadığım için mutlu olacağım, böylece statik olmayan bir alıcı yöntemimi alt sınıftaki bir statik değişkene erişmek için çağırabilirim ...

6
tallgirl
  • Msgstr "Statik yöntemlerin geçersiz kılınmaması için belirli bir neden var mı".

Bu soruyu sizin için tanımları doldurarak yeniden Word'e yazalım.

  • "Derleme zamanında çözülen yöntemlerin çalışma zamanında çözülememesinin belirli bir nedeni var mı?"

Ya da daha eksiksiz bir şekilde koymak gerekirse, bir örneği olmayan, ancak sınıfı tanıyan bir yöntemi çağırmak istersem, sahip olmadığım örneğe göre nasıl çözülebilirim.

5
Darron

Arayüzler, doğal olarak sınıflara değil, nesne örneklerine bağlı olan polimorfizm ile ilgilidir. Bu nedenle statik bir arayüz bağlamında anlam ifade etmez.

5
cliff.meyers

Statik yöntemler, örnek yöntemler gibi sanal değildir, bu yüzden Java tasarımcılarının onları arabirimlerinde istemediklerine karar verdiğini farz ediyorum.

Ancak arayüzlerin içine statik yöntemler içeren sınıflar koyabilirsiniz. Bunu deneyebilirsin!

public interface Test {
    static class Inner {
        public static Object get() {
            return 0;
        }
    }
}
5
Adrian Pronk

EDIT: As of Java 8, static methods are now allowed in interfaces. yorum yapan

Java 8'in arayüzlere girmesine izin verildiğinden statik yöntemler doğrudur, ancak örneğiniz hala çalışmayacaktır. Sadece statik bir yöntem tanımlayamazsınız: uygulamak zorundasınız veya bir derleme hatası alırsınız.

3
flavio

Genel olarak, statik olmayan arayüzler faydasızdır çünkü tüm statik yöntem çağrıları derleme zamanında çözümlenir. Yani, onlar için gerçek bir kullanım yok.

Jeneriklerle, varsayılan bir uygulama olsun ya da olmasın, kullanımları vardır. Açıkçası, geçersiz kılma vb. Olması gerekirdi. Ancak, benim tahminime göre, bu tür bir kullanım çok fazla değildiOO (diğer cevaplar açıkça belirtildiği gibi) ve dolayısıyla yararlı bir şekilde uygulamak için harcayacakları çabaya değmezdi.

2
MichaelGG

Birçok cevap, geçersiz kılınabilir statik yöntem kavramı ile ilgili problemleri tartışmıştır. Ancak, bazen kullanmak istediğin gibi göründüğü bir kalıpla karşılaşırsın.

Örneğin, değer nesnelerine sahip, ancak değer nesnelerini işlemek için komutları olan nesne-ilişkisel bir katmanla çalışıyorum. Çeşitli sebeplerden dolayı, her değer nesnesi sınıfı, çerçevenin komut örneğini bulmasına izin veren bazı statik yöntemler tanımlamalıdır. Örneğin, yapacağınız bir Kişi oluşturmak için:

cmd = createCmd(Person.getCreateCmdId());
Person p = cmd.execute();

ve bir Kişiyi, yapacağınız kimliğe göre yüklemek için

cmd = createCmd(Person.getGetCmdId());
cmd.set(ID, id);
Person p = cmd.execute();

Bu oldukça kullanışlıdır, ancak problemleri vardır; Özellikle statik yöntemlerin varlığı arayüzde uygulanamaz. Arabirimde geçersiz kılınabilen statik bir yöntem, tam olarak ihtiyacımız olan şey olurdu, eğer bir şekilde çalışabilseydi.

EJB'ler bu sorunu bir Ev arayüzü ile çözmekte; Her nesne Evini nasıl bulacağını bilir ve Ev "statik" yöntemleri içerir. Bu şekilde "statik" yöntemler gerektiği gibi geçersiz kılınabilir ve normal ("Uzak" olarak adlandırılır) arayüzünü çekirdekinize bir örnek için geçerli olmayan yöntemlerle karıştırmazsınız. Sadece normal arayüzün bir "getHome ()" yöntemi belirtmesini sağlayın. Home nesnesinin bir örneğini döndürün (ki bu bir singleton olabilir, sanırım) ve arayan kişi, tüm Person nesnelerini etkileyen işlemleri gerçekleştirebilir.

Why can't I define a static method in a Java interface?

Bir arabirimdeki tüm yöntemler açıkça soyuttur ve bu nedenle bunları statik olarak tanımlayamazsınız, çünkü statik yöntemler soyut olamaz.

2
Aniket Thakur

Bir arayüz asla statik olarak değiştirilemez, örn. ISomething.member. Bir arayüz her zaman, arayüzün bir alt sınıfının bir örneğini ifade eden bir değişken vasıtasıyla farklılaştırılır. Bu nedenle, bir arayüz referansı, bir alt sınıfının bir örneği olmadan hangi alt sınıfı ifade ettiğini asla bilemez.

Dolayısıyla, bir arayüzdeki statik bir yönteme en yakın yaklaşım, "bunu" görmezden gelen statik olmayan bir yöntem olabilir, yani örneğin statik olmayan üyelerine erişemez. Düşük seviyeli soyutlamada, statik olmayan her yöntem (herhangi bir denemede arandıktan sonra) gerçekten sadece "bunu" örtük biçimsel bir parametre olarak alan sınıf kapsamına sahip bir işlevdir. Bu kavramın kanıtı olarak Scala'nın singleton nesnesi ve Java ile birlikte çalışabilirlik konusuna bakın. Ve böylece her statik yöntem "this" parametresi almayan sınıf kapsamına sahip bir fonksiyondur. Bu nedenle normal olarak statik bir yöntem statik olarak adlandırılabilir, ancak daha önce belirtildiği gibi bir arayüzün uygulaması yoktur (soyuttur).

Dolayısıyla, bir arayüzdeki statik bir yönteme en yakın yaklaşımı elde etmek için, statik olmayan bir yöntem kullanmaktır, ardından statik olmayan örnek üyelerinden hiçbirine erişemezsiniz. Başka hiçbir şekilde olası bir performans avantajı olmazdı, çünkü (derleme zamanında) bir ISomething.member() işlevini statik olarak bağlamanın bir yolu yoktu. Arabirimde statik bir yöntem gördüğüm tek yarar, bunun "gizli" bir örtülü girişi girmemesi (yani yok sayması) ve dolayısıyla statik olmayan örnek üyelerinden hiçbirine erişimi engellememesidir. Bu, "buna" erişmeyen işlevin değişmez olduğunu ve içerdiği sınıfa göre bile salt okunur olmadığını açıklar. Ancak ISomething arabiriminde "statik" bildirimi, derleyiciye neden olan ISomething.member() işleviyle erişmeye çalışan kişilerin kafasını karıştırır. Derleyici hatası yeterince açıklayıcı olsaydı, insanları burada istediklerini (görünüşte çoğunlukla fabrika yöntemleri) yapmak istediklerini (görünüşte çoğunlukla fabrika yöntemleri) gerçekleştirmek için statik olmayan bir yöntem kullanma konusunda eğitmeye çalışmaktan daha iyi olurdu. Bu sitede Q & A kez), bu yüzden açıkça birçok kişi için sezgisel olmayan bir konudur. Doğru anlama için bir süre düşünmem gerekiyordu.

Bir arabirimde değişken bir statik alan elde etmenin yolu, bir arabirimde statik olmayan alıcı ve ayarlayıcı yöntemlerini kullanmaktır, alt sınıftaki statik alana erişmek için kullanılır. Sidenote, görünüşe göre değişmez statik, Java arayüzünde static final ile bildirilebilir.

1
Shelby Moore III

Uygulanabilecek bir şey statik arayüzdür (arayüzdeki statik yöntem yerine). Belirli bir statik arayüzü uygulayan tüm sınıflar, karşılık gelen statik yöntemleri uygulamalıdır. Kullanarak herhangi bir Class clazz'den SI statik arayüzünü alabilirsiniz.

SI si = clazz.getStatic(SI.class); // null if clazz doesn't implement SI
// alternatively if the class is known at compile time
SI si = Someclass.static.SI; // either compiler errror or not null

o zaman si.method(params)'yi çağırabilirsiniz. Bu yararlı olacaktır (örneğin fabrika tasarımı için) çünkü SI statik metotların uygulanmasını derleme zamanı bilinmeyen bir sınıftan alabilirsiniz (veya uygulanmasını kontrol edebilirsiniz)! Dinamik bir gönderme gereklidir ve bir sınıfın statik yöntemlerini (final değilse) genişleterek (statik arabirimden çağrıldığında) geçersiz kılabilirsiniz. Açıkçası, bu yöntemler yalnızca sınıflarının statik değişkenlerine erişebilir.

0

Arayüzlerde statik yöntemlere izin verildiğini varsayalım: * Tüm uygulama sınıflarını bu yöntemi bildirmeye zorlarlardı. * Arayüzler genellikle nesneler aracılığıyla kullanılır, bu nedenle bunlar üzerinde etkili olan tek yöntem statik olmayanlardır. * Belirli bir arayüzü bilen herhangi bir sınıf statik yöntemlerini çağırabilir. Dolayısıyla bir uygulayıcı sınıfın 'statik metodu' altına çağrılacaktı ancak invoker sınıf hangisini bilmiyor. Nasıl bilebiliriz? Bunu tahmin etmek için somutlaşma yok!

Arayüzlerin nesnelerle çalışırken kullanılması düşünülmüştü. Bu şekilde, bir nesne belirli bir sınıftan başlatılır, bu yüzden bu son mesele çözülür. Çağıran sınıfın hangi sınıfın olduğunu bilmesi gerekmez, çünkü örnekleme üçüncü sınıf tarafından yapılabilir. Yani çağıran sınıf sadece arayüzü bilir.

Bunun statik yöntemlere genişletilmesini istiyorsak, daha önce bir uygulayıcı sınıfı belirleme olanağına sahip olmalıyız, sonra da çağıran sınıfa bir referans iletmeliyiz. Bu, sınıfı arabirimdeki statik yöntemlerle kullanabilir. Fakat bu referans ile bir nesne arasındaki fark nedir? Sadece sınıfın ne olduğunu gösteren bir nesneye ihtiyacımız var. Şimdi, nesne eski sınıfı temsil eder ve eski statik yöntemler de dahil olmak üzere yeni bir arayüz uygulayabilir - bunlar statik değildir.

Metasınıflar bu amaca hizmet eder. Java sınıfını deneyebilirsiniz. Ancak sorun şu ki, Java bunun için yeterince esnek değil. Bir arabirimin sınıf nesnesindeki bir yöntemi bildiremezsiniz.

Bu meta bir sorundur - eşek yapmanız gerektiğinde

..

yine de, kolay bir geçici çözüm varsa - bu yöntemi aynı mantıkla durağan hale getirin. Ama sonra yöntemi çağırmak için önce bir nesne yaratman gerekirdi.

0
beibichunai

Arayüzler, bir sınıfın sağlayacağı şeylerin bir listesini sağlar, bu şeylerin gerçek bir uygulaması değil, statik öğenizin ne olduğu.

Statik istiyorsanız, soyut bir sınıf kullanın ve miras alın, aksi takdirde, statik kaldırın.

Umarım yardımcı olur!

0
samoz

Java 8'in bu sorunu çözdüğünü fark ederken, şu anda üzerinde çalışmakta olduğum bir senaryo ile çalışacağımı (Java 7 ile kilitlenmiş) bir arayüzde statik yöntemler belirleyebilmenin faydalı olabileceğini düşündüm.

"İd" ve "displayName" alanlarını, çeşitli sebeplerle değerleri değerlendiren yardımcı yöntemlerle birlikte tanımladığım birkaç enum tanımına sahibim. Bir arabirim uygulamak, alıcı yöntemlerinin yerinde olduğunu ancak statik yardımcı yöntemlerin kullanılmadığından emin olmamı sağlar. Bir numara olarak, yardımcı yöntemleri kalıtsal bir soyut sınıfa ya da benzer bir şeye boşaltmanın temiz bir yolu yoktur, bu yüzden yöntemlerin enumda tanımlanması gerekir. Ayrıca, bir enum olduğundan, onu aslında bir nesnel nesne olarak geçiremez ve arabirim türü olarak kabul edemezsiniz, ancak statik yardımcı yöntemlerin bir arabirim aracılığıyla varlığını gerektirebilmeyi sevdim. Java 8'de destekleniyor.

İşte benim amacımı gösteren kod.

Arayüz tanımı:

public interface IGenericEnum <T extends Enum<T>> {
    String getId();
    String getDisplayName();
    //If I was using Java 8 static helper methods would go here
}

Bir enum tanımı örneği:

public enum ExecutionModeType implements IGenericEnum<ExecutionModeType> {
    STANDARD ("Standard", "Standard Mode"),
    DEBUG ("Debug", "Debug Mode");

    String id;
    String displayName;

    //Getter methods
    public String getId() {
        return id;
    }

    public String getDisplayName() {
        return displayName;
    }

    //Constructor
    private ExecutionModeType(String id, String displayName) {
        this.id = id;
        this.displayName = displayName;
    }

    //Helper methods - not enforced by Interface
    public static boolean isValidId(String id) {
        return GenericEnumUtility.isValidId(ExecutionModeType.class, id);
    }

    public static String printIdOptions(String delimiter){
        return GenericEnumUtility.printIdOptions(ExecutionModeType.class, delimiter);
    }

    public static String[] getIdArray(){
        return GenericEnumUtility.getIdArray(ExecutionModeType.class);
    }

    public static ExecutionModeType getById(String id) throws NoSuchObjectException {
        return GenericEnumUtility.getById(ExecutionModeType.class, id);
    }
}

Genel enum yardımcı programı tanımı:

public class GenericEnumUtility {
    public static <T extends Enum<T> & IGenericEnum<T>> boolean isValidId(Class<T> enumType, String id) {       
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(enumOption.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String printIdOptions(Class<T> enumType, String delimiter){
        String ret = "";
        delimiter = delimiter == null ? " " : delimiter;

        int i = 0;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(i == 0) {
                ret = enumOption.getId();
            } else {
                ret += delimiter + enumOption.getId();
            }           
            i++;
        }

        return ret;
    }

    public static <T extends Enum<T> & IGenericEnum<T>> String[] getIdArray(Class<T> enumType){
        List<String> idValues = new ArrayList<String>();

        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            idValues.add(enumOption.getId());
        }

        return idValues.toArray(new String[idValues.size()]);
    }

    @SuppressWarnings("unchecked")
    public static <T extends Enum<T> & IGenericEnum<T>> T getById(Class<T> enumType, String id) throws NoSuchObjectException {
        id = id == null ? "" : id;
        for(IGenericEnum<T> enumOption : enumType.getEnumConstants()) {
            if(id.equals(enumOption.getId())) {
                return (T)enumOption;
            }
        }

        throw new NoSuchObjectException(String.format("ERROR: \"%s\" is not a valid ID. Valid IDs are: %s.", id, printIdOptions(enumType, " , ")));
    }
}
0
Ryan

Bir arabirimde statik yöntemleri tanımlayamazsınız, çünkü statik yöntemler bir sınıf örneğine değil bir sınıfa aittir ve arabirimler Sınıflar değildir. Buradan daha fazla bilgi edinin.

Ancak, isterseniz bunu yapabilirsiniz:

public class A {
  public static void methodX() {
  }
}

public class B extends A {
  public static void methodX() {
  }
}

Bu durumda elinizde olan, methodX () adı verilen 2 farklı statik yöntemle iki sınıftır.

0
Handerson

Yapabileceğini varsayalım; bu örneği düşünün:

interface Iface {
  public static void thisIsTheMethod();
}

class A implements Iface {

  public static void thisIsTheMethod(){
    system.out.print("I'm class A");
  }

}

class B extends Class A {

  public static void thisIsTheMethod(){
    System.out.print("I'm class B");
  } 
}

SomeClass {

  void doStuff(Iface face) {
    IFace.thisIsTheMethod();
    // now what would/could/should happen here.
  }

}
0
pvgoddijn

Bunu çözmek için: hata: eksik yöntem gövdesi veya soyut statik void main (String [] args);

interface I
{
    int x=20;
    void getValue();
    static void main(String[] args){};//Put curly braces 
}
class InterDemo implements I
{
    public void getValue()
    {
    System.out.println(x);
    }
    public static void main(String[] args)
    {
    InterDemo i=new InterDemo();
    i.getValue();   
    }

}

çıkış: 20

Şimdi arayüzde statik yöntemi kullanabiliriz

0
ashish pawar