Neden bir arabirimdeki tüm alanlar örtük olarak statik ve nihaidir?


100

Sadece bir Arayüzde tanımlanan tüm alanların neden örtük olarak staticve olduğunu anlamaya çalışıyorum final. Alanları tutma fikri staticbana mantıklı geliyor çünkü bir arayüzün nesnelerine sahip olamıyorsunuz ama neden final(örtük olarak)?

Java tasarımcıları bir arayüz alanları yapmakla gitmesinin herhangi biri bilir staticve final?


Kendim için bir not: Bu statik çünkü arayüz alanları onu uygulayan nesnenin bir parçası olmayacak.
Raining

Yanıtlar:


126

Bir arayüzün davranışı veya durumu olamaz çünkü sadece bir etkileşim sözleşmesi belirtmesi amaçlanmıştır, uygulama ayrıntısı yoktur. Yöntem / yapıcı gövdelerine veya statik / örnek başlatan bloklara izin verilmeyerek 'davranış yok' uygulanır. "Durum yok" yalnızca statik son alanlara izin verilerek uygulanır. Bu nedenle, sınıfın bir durumu (statik durum) olabilir, ancak örnek durumu arabirim tarafından çıkarılmaz.

BTW: Java'da bir sabit, statik bir son alanla tanımlanır (ve geleneksel olarak ad UPPER_CASE_AND_UNDERSCORES kullanır).


54
Nihai alanların sabit olduğu doğru değildir; bu yalnızca ilkel türler için garantilidir. Genel olarak, son anahtar kelime yalnızca bellek konumunun değişmeyeceği anlamına gelir.
Pops

8
Son alanların sabit olduğunu söylemedim, sadece sabitlerin son alanlar olduğunu söylemedim. Bir arabirime ilkel olmayan statik bir son alan koymaya izin verildiğini unutmayın. Bu alanın içeriği değişse bile, ona yapılan referans sabittir.
Adriaan Koster

1
@AdriaanKoster Kesin olarak son alanın sabit olduğunu söylediniz: Hiçbir durum yalnızca sabitlere izin verilerek zorlanmaz. - bu cümle, tüm son alanların sabit olduğunu ima eder. Kullandığınız kelimeler hakkında daha fazla tartışmaya çalışabilirsiniz, ancak açıkçası ifadeniz yanıltıcıdır.
Tomáš Zato - Monica'yı eski durumuna getir

2
Zayıflayan zihnim olmalı ama bu cevaba altı yıl baktıktan sonra, ki bu benim en iyi cevabım oluyor, hala yorumları anlamıyorum. Lütfen farklı bir ifade önerin çünkü yanlış bir şey göremiyorum.
Adriaan Koster

Java tasarımcılarının amacı bir arabirimi durumsuz yapmak olabilirdi, ancak başarısız oldular çünkü bir örnek alanı değiştirilebilir bir sınıf olabilir. Başarısız olduklarını kabul etmek yerine, java'da alabileceğiniz kadar gerçeğe static finalyakın olan (gerçek C / C ++) örnek alanlarını zorlamayı seçerler const. Ne yazık ki bu örtüktür ve uzman olmayanlar için kafa karışıklığına yol açabilir. (Sadece fark ettim staticçünkü istenmeyen davranışlar gözlemledim. Bunların finalsadece bu cevaptan olduğunu öğrendim .)
kullanıcı değil

27

Olma nedeni final

Nihai olarak tanımlanmamışlarsa, herhangi bir uygulama alanların değerini değiştirebilir. Daha sonra uygulamanın bir parçası olurlar. Arayüz, herhangi bir uygulama içermeyen saf bir özelliktir.

Olma nedeni static

Statik iseler, ne nesneye ne de nesnenin çalışma zamanı türüne değil, arayüze aittirler.


18

Burada parlatılan birkaç nokta var:

Bir arayüzdeki alanların örtük olarak statik nihai olması, bunların derleme zamanı sabitleri veya hatta değişmez olmaları gerektiği anlamına gelmez. Örneğin tanımlayabilirsiniz

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(Bunu bir ek açıklama tanımının içinde yapmanın javac'ın kafasını karıştırabileceğine dikkat edin , yukarıdakilerin aslında statik bir başlatıcıda derlendiği gerçeğiyle bağlantılı olarak.)

Ayrıca, bu kısıtlamanın nedeni teknik olmaktan çok stilistiktir ve birçok insan rahatlatıldığını görmek ister .


9

Alanlar, soyut olamazlar (yöntemler gibi) statik olmalıdır. Soyut olamayacakları için, uygulayıcılar alanların farklı uygulamalarını mantıksal olarak sağlayamayacaklardır.

Alanların son olması gerektiğini düşünüyorum, çünkü alanlara birçok farklı uygulayıcı tarafından erişilebilmesi değiştirilebilir olmalarına izin veriyor (senkronizasyon olarak) sorunlu olabilir. Ayrıca yeniden uygulanmasını önlemek için (gizli).

Benim düşüncem.


NawMan, "Keçeler statik olmalı ..." hakkındaki açıklamanız pek mantıklı değil. Ama "Alanlar kesin olmalı ..." konusunda çok haklıydın
peakit

1
Alanların neden son olması gerektiği konusunda haklı olduğunu sanmıyorum. Farklı uygulayıcıların bir alanı değiştirmesine izin vermek sorunlu değildir, çünkü aksi takdirde kalıtım sorunlu olacaktır. Adriaan'ın dediği gibi alanlar son olmalıdır, çünkü bir arayüz durumsuzdur ve olması gerekir. Durumlu bir arayüz temelde soyut bir sınıf olmalıdır.
Axelle Ziegler

Eğer bir varsa public staticdeğil alanını final, findbugs (haklı olarak!) Şikayet edecektir.
Tom Hawtin -

2

Alanların son derece kısıtlayıcı olması gerekliliğini ve Java dili tasarımcılarının bir hatası olduğunu düşünüyorum. Arayüz tipindeki bir nesne üzerinde işlemler gerçekleştirmek için gerekli olan uygulamada sabitleri ayarlamanız gereken zamanlar vardır, örneğin ağaç işleme. Uygulama sınıfında bir kod yolu seçmek bir kludge'dir. Kullandığım geçici çözüm, bir arabirim işlevi tanımlamak ve bir değişmez değer döndürerek onu uygulamaktır:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

Bununla birlikte, bu sözdizimini kullanmak daha basit, daha net ve anormal uygulamaya daha az eğilimli olacaktır:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}

Alanların nihai olmaktan çok durağan olmasından şikayet ediyor gibisin.
Daniel Yankowsky

0

Şartname, sözleşmeler ... Alan erişimi için makine talimatı, nesne adresi artı alan ofsetini kullanır. Sınıflar birçok arabirimi uygulayabildiğinden, bu arabirimi genişleten tüm sınıflarda aynı ofsete sahip nihai olmayan arabirim alanını yapmanın bir yolu yoktur. Bu nedenle, alan erişimi için farklı bir mekanizma uygulanmalıdır: bir artı sanal alan tablosu türü (sanal yöntem tablosunun analogu) yerine iki bellek erişimi (alan ofsetini al, alan değerini al). Sanırım onlar sadece mevcut şeyler (yöntemler) aracılığıyla kolayca simüle edilebilen işlevsellik için jvm'yi karmaşıklaştırmak istemediler.

Ölçeklendirmede, arayüzlerde alanlar olabilir, ancak bunlar yukarıda açıkladığım gibi (yöntem olarak) dahili olarak uygulanmaktadır.


-1

static:

Olan herhangi bir şey (değişken ya da metodu) staticJava olarak getirilebilir Classname.variablenameya Classname.methodnameda doğrudan. Sadece nesne adını kullanarak çağırmak zorunlu değildir.

Arayüzde, nesneler bildirilemez ve staticnesne adına ihtiyaç duymadan sadece sınıf adı aracılığıyla değişkenleri çağırmayı mümkün kılar.

final:

Alt sınıflarında geçersiz kılınamayacağı için bir değişken için sabit bir değer sağlamaya yardımcı olur.

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.