Java arabirimindeki yöntemler, genel erişim değiştiricisi ile veya bu arabirim olmadan bildirilmelidir mi?


292

Java arabirimindeki yöntemler publicerişim değiştiricisiyle veya değiştiriciyle bildirilmeli mi?

Teknik olarak elbette önemli değil. An uygulayan bir sınıf yöntemi interfaceher zaman public. Fakat daha iyi bir sözleşme nedir?

Java'nın kendisi bu konuda tutarlı değildir. Örneğin bakınız Collectionvs Comparableveya Futurevs. ScriptEngine.


22
Genel durumuna yazma o ima çünkü kötü olabilir kamuya açık olmayan olmak
Pacerier

8
Herhangi bir formun yedek söz diziminden kaçınmalısınız.
Lorne Marquis

3
Bunun kullanmak kötü olduğunu kabul ederken @Pacerier, publicbu bağlamda, varsayılan arayüz yöntemleri olabilir şimdi (java 9) ile özel olması. Eski olduğu için yorumunuzu kaldırmanızı öneririm.
aioobe

2
Evet, işler Java 9. değişikliği tabidir "genel durumuna Yazma o ima edebilir kamuya açık olmayan olmak" . Java 9'da tam olarak bu mümkün olduğu için, bu argüman şimdi gerçekten yazmanın yararına public.
MC İmparatoru

Yanıtlar:


334

JLS Bundan da anlaşılacağı:

Bir arabirimde bildirilen bir yöntemin publicve / veya abstractdeğiştiricinin yedek olarak belirtilmesine izin verilir, ancak bir stil meselesi olarak önerilmez .


6
Yukarıdaki JLS bağlantısı, okuduğum sırada Java 7 içindi. Java 9 hakkında halka açık olmayan yöntemlere izin veren yorumlardan sonra, SE9 JLS için hala çok benzer ifadelerin olduğunu doğrulamak istedim . ( publicbölüm aynı, and/or abstractbölüm düşürüldü)
OzgurH

3
Hala gerçek SE11 JLS
Ortomala Lokni


44

Genel değiştirici Java arabirimlerinde atlanmalıdır (bence).

Fazladan bilgi eklemediğinden, önemli şeylerden sadece dikkat çeker.

Çoğu stil kılavuzu onu dışarıda bırakmanızı önerecektir, ancak elbette en önemli şey kod tabanınız boyunca ve özellikle her arabirim için tutarlı olmaktır. Aşağıdaki örnek, Java'da% 100 akıcı olmayan birini kolayca karıştırabilir:

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}

3
Böyle bir stil rehberine bağlantınız var mı?
Benno Richters

9
Tutarlılık en önemli şeydir ve bu tür soruların% 99'unun cevabıdır.
SCdF

Anlaşılan yeniden tutarlılık. Kodlama standartları için bir şey belgeler çocuklar :)
JeeBee

2
Bno: Bir örnek Java Dil Spesifikasyonu, diğeri Checkstyle.
Rasmus Faber

9

Bu sorunun uzun zaman önce sorulmuş olmasına rağmen, kapsamlı bir açıklamanın neden bir arabirimin sabitlerinden önce yöntemler ve genel statik final kullanımına neden gerek olmadığını açıklığa kavuştuğunu hissediyorum.

Her şeyden önce, arabirimler, her sınıfın benzersiz bir uygulamaya sahip olacağı ilişkisiz sınıflar kümesi için ortak yöntemler belirtmek için kullanılır. Bu nedenle, geçersiz kılınacak diğer sınıflar tarafından erişilemediğinden erişim değiştiriciyi özel olarak belirtmek mümkün değildir.

İkincisi, bir arabirim türündeki nesneleri başlatabilse de, onu uygulayan ve miras alınmayan sınıflar tarafından bir arabirim gerçekleştirilir. Ve bir arabirim aynı pakette olmayan farklı ilişkisiz sınıflar tarafından uygulanabileceğinden (gerçekleştirildiğinden), korumalı erişim değiştirici de geçerli değildir. Bu yüzden erişim değiştirici için sadece herkese açık seçim kalıyoruz.

Üçüncüsü, bir arabirimin örnek değişkenleri ve yöntemleri de dahil olmak üzere herhangi bir veri uygulaması yoktur. Arabirimde uygulanan yöntemleri veya örnek değişkenleri eklemek için mantıklı bir neden varsa, bir arabirim değil miras hiyerarşisinde bir üst sınıf olmalıdır. Bu gerçeği göz önünde bulundurarak, bir arayüzde hiçbir yöntem uygulanamayacağı için, arayüzdeki tüm yöntemler soyut olmalıdır.

Dördüncüsü, Interface sadece veri üyeleri olarak sabit içerebilir, bu da nihai olmaları gerektiği anlamına gelir ve elbette nihai sabitler yalnızca bir örneğini tutmak için statik olarak bildirilir. Bu nedenle, arabirim sabitleri için statik final de bir zorunluluktur.

Sonuç olarak, bir arabirimin sabitleri önce genel özeti ve genel statik finali kullanmasına rağmen, başka bir seçenek olmadığından gereksiz olarak kabul edilir ve kullanılmaz.


7

Tanıtılmasıyla private, static, defaultJava 9/8 arayüz yöntemleri için değiştiricileri, işler daha karmaşık almak ve bunu tam beyanlar (Java 9 derlemek gerekiyor) daha okunabilir olduğunu düşünüyorum eğilimindedir:

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}

5

Varsayılan olarak uygulanan değiştiricileri koymaktan kaçınırım. Belirtildiği gibi, tutarsızlık ve karışıklığa yol açabilir.

Gördüğüm en kötü yöntem beyan edilen yöntemlerle bir arayüz abstract...


5

Ben publicdeğiştirici ile beyan yöntemleri kullandım , çünkü özellikle sözdizimi vurgulama ile, kodu daha okunabilir hale getirir. Yine de en son projemizde public, arayüz yöntemlerinde değiştiriciler için varsayılan yapılandırma ile bir uyarı gösteren Checkstyle kullandık , bu yüzden onları devreye sokmaya başladım.

Bu yüzden neyin en iyi olduğundan emin değilim, ama gerçekten sevmediğim bir şey public abstractarayüz yöntemlerini kullanmak. Eclipse bunu bazen "Extract Interface" ile yeniden düzenleme yaparken yapar.


2
Ancak yalnızca iki onay kutusunu işaretlerseniz yöntemleri herkese açık, özet olarak bildirin.
MetroidFan2002

4

Arabirim olmasaydı her zaman ne kullanacağımı yazıyorum ve doğrudan bir uygulama yazıyordum, yani kullanıyordum public.


6
Tüm arabirim yöntemleri özetini de açıkça bildirir misiniz?
Dan Dyer

4
Soyut bir sınıf değil, bir arayüz. 'Herkese açık' ile ilgili olarak, düşündüğünüz zaman yazdığınız 7 karakter, büyük anlaşma! Ve uygulamada da nasıl tanımlanacağı, yani yedeklilik için -1'i dengeleyen tutarlılık için +1.
JeeBee

3

Atlamayı tercih ederim, arayüzlerin varsayılan olarak olduğu bir yerde okudum publicve abstract.

Şaşırtıcı bir şekilde - Head First Design Patterns (Ara İlk Tasarım Desenleri) , publicarayüz bildirimi ve arayüz yöntemleri ile kullanıyor ... beni bir kez daha yeniden düşünmeye itti ve bu yazıya indim.

Her neyse, gereksiz bilgilerin göz ardı edilmesi gerektiğini düşünüyorum.


1
Eğer ihmal varsa Sadece netleştirmek için publico zaman olacak arabirim bildiriminde erişim değiştiricisi değil varsayılan olarak kamu ve soyut. docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad

3

Popüler yanıta katılmıyorum, kamuoyuna sahip olmanın başka seçenekler olduğunu ima ediyor ve bu yüzden orada olmamalı. Gerçek şu ki, Java 9 ve ötesinde diğer seçenekler var.

Bunun yerine Java'nın 'genel' belirtilmesini zorunlu kılması / zorlaması gerektiğini düşünüyorum. Neden? Çünkü bir değiştiricinin olmaması, 'paket' erişiminin her yere erişmesi anlamına gelir ve buna özel bir durum olarak sahip olmak karışıklığa yol açan şeydir. Açık bir mesajla derleme hatası yaptıysanız (örn. "Bir arayüzde paket erişimine izin verilmez."), 'Herkese açık' bırakma seçeneğinin getirdiği görünen belirsizlikten kurtulurduk.

Şu anki ifadeye dikkat edin : https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

"Bir arabirimin gövdesindeki bir yöntem genel veya özel olarak bildirilebilir (§6.6). Hiçbir erişim değiştiricisi verilmezse, yöntem dolaylı olarak herkese açıktır. Genel olarak gereksiz bir şekilde belirtilmesine izin verilir, ancak bir stil meselesi olarak önerilmez bir arabirimde yöntem bildirimi için değiştirici. "

Şimdi 'özel' IS'ye izin verildiğini görün. Son cümlenin JLS'den kaldırılması gerektiğini düşünüyorum. "Örtük olarak halka açık" davranışa, geriye dönük uyumluluk için muhtemelen devam edeceğinden ve erişim değiştiricisinin yokluğunun, arayüzlerde 'kamu' anlamına geldiği ve başka bir yerde 'paket' olduğu karışıklığına yol açtığı için, talihsiz bir durumdur.


2

Arayüzlerdeki yöntemlerin varsayılan olarak kamusal ve soyut olmasının nedeni benim için oldukça mantıklı ve açıktır.

Bir arabirimdeki yöntem, varsayılan olarak, uygulayıcı sınıfı bir uygulama sağlamaya zorlamaktır ve varsayılan olarak uygulayıcı sınıfın buna erişimi vardır.

Bu değiştiricileri kodunuza eklemek gereksizdir ve işe yaramaz ve yalnızca Java temel bilgileri hakkında bilgi ve / veya anlamadığınız sonucuna yol açabilir.


Ancak, soyut bir sınıfta erişimi koruyan soyut yöntemleri de uygulayabilirsiniz. Yani halka açık bir gereklilik değil. Varsayılan olanla aynı olan açık bir şey eklemek her zaman gereksizdir, ancak her zaman işe yaramaz.
swpalmer

Ama soru arayüzler hakkında. Konuya girmek istemedim. Yani, Java 8'den beri, arayüzlerde özel ve varsayılan yöntem hakkında da konuşabiliriz, değil mi? Bu yüzden eğer istersek bu tartışma oldukça uzun sürebilir. ;)
Iuliana Cosmina

1

Tamamen öznel. Gereksiz publicgibi görünen gereksiz değiştiriciyi atlıyorum. Başkaları tarafından belirtildiği gibi - tutarlılık bu kararın anahtarıdır.

C # dil tasarımcılarının bunu uygulamaya karar verdiğini belirtmek ilginçtir. Bir arabirim yöntemini C # içinde genel olarak bildirmek aslında bir derleme hatasıdır. Tutarlılık muhtemelen diller arasında önemli değildir, bu yüzden sanırım bu Java ile doğrudan ilgili değildir.


-9

İnsanlar arayüzünüzü IDE'deki veya Javadoc'daki kod tamamlamasından öğrenecekler, kaynağı okuyarak değil. Yani kaynağa "herkese açık" koymanın bir anlamı yok - kimse kaynağı okumuyor.


8
Gerçekten kimsenin kaynağı okumadığına dair bir fikre katılmıyorum. Bence birçok insan koda yakınlaştırmak için Eclipse'de F3 kullanmaktadır. Maven gibi araçlar bir sebepten ötürü sadece JavaDoc'u değil kaynakları indirme seçeneğini sunar.
Benno Richters

publicBir arabirime erişim değiştirici eklememenin tam nedeni bu değildir . Tasarım ve arkasındaki dikkatli bir düşünmeden sonra.
mtk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.