Arayüz değişkenleri neden varsayılan olarak statik ve sonlandır?


274

Java'da arayüz değişkenleri neden varsayılan olarak statik ve sondur?


41
Arayüzlerin içine herhangi bir değişken koymamalısınız.
Mart'ta cherouvim

34
Çünkü arayüzler çeşitli şekillerde uygulanabilecek sözleşmeleri tanımlar. Değişkenin değeri uygulamadır.
cherouvim

10
Arayüzü uygulayan tüm sınıfların bazı sabit değişkenleri olduğunu bildiğimizde kesinlikle yapabiliriz (örneğin Alan adları).
Aniket Thakur

Sınıftaki bir değişkeni, sınıfın uyguladığı arabirimin bir örneği yapmak iyi bir fikir mi? Bunu daha önce duymuştum.
Doug Hauf

Java'daki arayüzler, C'deki normalizasyon nedeniyle nihai olan ACID prensibini takip eder. @Cherouvim Bir değişkenin türü uygulamadır, bir değişkenin değeri olsun veya olmasın bildirilmelidir ve bir değişkenin tanımı değerdir. Değişkenin değerini değiştirirseniz yeniden uygulama olmaz, yeniden tanımlanması gerekir.
Grim

Yanıtlar:


264

Philip Shaw'un Java arayüz tasarımı SSS bölümünden:

Java arabirimleri kendi başlarına başlatılamadığından, arabirim değişkenleri statiktir; değişkenin değeri, içinde hiçbir örnek bulunmayan statik bir bağlamda atanmalıdır. Son değiştirici, arabirim değişkenine atanan değerin, program kodu tarafından yeniden atanamayan gerçek bir sabit olmasını sağlar.

kaynak


39
Soyut sınıfların da "kendi başlarına" örneklenemeyeceğini ve bunların örnek değişkenleri olabileceğini unutmayın.
macias

18
staticDeğiştirici için bu açıklama tamamen sahte. Bir sınıfın genel yönetim ortamı değişkenleri, arabiriminin bir parçasıdır ve interfacetıpkı yönetim ortamı yöntemlerinde olduğu gibi bir Java'da soyutlanmamalarının bir nedeni yoktur . Bir Java'nın interfacedoğrudan somutlaştırılamaması önemli değildir - yine de uygulayan sınıf örneklerine sahip olabilirsiniz interfaceve belirli bir ortak örnek değişkenine sahip olmalarını gerektirebilir. finalBununla ilgili olarak , bu hiç bir açıklama sunmuyor - sadece ne finalanlama geldiğini açıklıyor .
pyrocrasty

3
Yukarıdaki alıntı bağlamda daha iyidir. Bunun nedeni, "arabirim değişkenlerinin Java sabitleri olması amaçlanmıştır". Alıntı, böyle bir sabitin neden statik ve nihai olacağı üzerinde duruyordu. Bu doğru, ancak asıl soru şu: gerçek arayüzün bir parçası olarak değişkenlere neden izin verilmiyor (yani, bir uygulayıcı sınıfta olması gereken özel olmayan üyelerin adlarını ve türlerini belirtmek). Özel "arabirim sabitleri" isteselerdi, yeni sözdizimi kullanabilirler ya da bir arabirimde gerçekte tanımlanan değişkenlerin arabirim sabitleri olduğuna karar verebilirlerdi .
pirorasti

6
Durum sorunlarının birden fazla mirasını önlemek için arabirimlerde örnek değişkenleri olamaz. Bkz. Docs.oracle.com/javase/tutorial/java/IandI/… . Bir sınıf aynı nedenden ötürü birden fazla sınıfı genişletemez.
denis

1
Varsayılan yöntemler nasıl tanıtılır ve bunların örneği vardır, ancak örnek değişkeni desteklenmez ...
M.kazem Akhgary

41

Arayüz doğrudan bir nesneye sahip olmadığından, bunlara erişmenin tek yolu bir sınıf / arayüz kullanmaktır ve bu nedenle arayüz değişkeni varsa statik olmalıdır, aksi takdirde dış dünyaya erişilemez. Statik olduğu için, sadece bir değeri tutabilir ve onu uygulayan herhangi bir sınıf onu değiştirebilir ve bu yüzden her şey dağınık olacaktır.

Dolayısıyla, eğer bir arayüz değişkeni varsa, dolaylı olarak statik, nihai ve açık bir şekilde halka açık olacaktır !!!


Elbette bir örnek değişkenine Java'da izin verilmişse erişilebilir interface. Bir sınıf, örnek değişkeni (arabirimin gerektirdiği gibi) bildirerek arabirimi uygular. Yapıcısı (veya başka bir yöntem) örnek değişkenini ayarlar. Sınıfın bir örneği başlatıldığında, örnek değişkenine erişebileceksiniz.
pirorasti

Java, bir arabirimde gövdeli statik yöntemlerin bulunmasına izin verir. Bunlar statik değişkenlere erişebilir. Bunları değiştiremezler, yani statik fonksiyonlar herhangi bir veri depolayamaz
simpleuser

36

public : arayüzde bulunan yöntemler gibi tüm sınıflara erişilebilirlik için

static : arabirimin bir nesnesi olamaz, interfaceName.variableName ona veya doğrudan uygulayan sınıftaki değişkenName'e başvurmak için kullanılabilir.

nihai : sabit yapmak. 2 sınıf aynı arabirimi uygular ve her ikisine de değeri değiştirme hakkını verirseniz, var değerinin geçerli değerinde çakışma olur, bu nedenle yalnızca bir kez başlatmaya izin verilir.

Ayrıca tüm bu değiştiriciler bir arayüz için örtüktür, gerçekten herhangi birini belirtmeniz gerekmez.


15

( Bu felsefi bir cevap değil, daha pratik bir cevaptır ). Değiştirici gereksinimi staticaçıktır ve bunlar başkaları tarafından cevaplanmıştır. Temel olarak, arayüzler somutlaştırılamadığından, alanlarına erişmenin tek yolu onları bir sınıf alanı yapmaktır -static .

interfaceAlanların otomatik olarak final(sabit) hale gelmesinin nedeni , farklı uygulamaların yanlışlıkla diğer uygulamaların davranışını etkileyebilecek arabirim değişkeninin değerini değiştirmesini önlemektir. Bir interfacemülkün açıkça finalJava tarafından oluşturulmadığı aşağıdaki senaryoyu düşünün :

public interface Actionable {
    public static boolean isActionable = false;

    public void performAction();
}

public NuclearAction implements Actionable {

    public void performAction() {
        // Code that depends on isActionable variable
        if (isActionable) {
            // Launch nuclear weapon!!!
        }
    }
}

Şimdi, uygulayan başka bir sınıf Actionablearabirim değişkeninin durumunu değiştirirse ne olacağını düşünün :

public CleanAction implements Actionable  {

    public void performAction() {
        // Code that can alter isActionable state since it is not constant
        isActionable = true;
    }
}

Bu sınıflar classloader tek bir JVM içinde yüklenir, daha sonra davranışı NuclearActionbaşka bir sınıf ile etkilenebilir, CleanActiononun zaman performAction()sonra çağırmak olduğuCleanAction bu felaket bu durumda özellikle olabilir (aksi takdirde, aynı iplik ya da) yürütülür (anlamsal olarak bu).

A'nın her bir uygulamasının interfacebu değişkenleri nasıl kullanacağını bilmediğimizden , örtük olarak olmalıdırlar final.


9

Çünkü başka bir şey uygulamanın bir parçasıdır ve arayüzler herhangi bir uygulamayı içeremez.


1
o zaman finalin sebebi nedir.
Jothi

7
Bunun sabit olduğunu belirtmek için. Java'nın const anahtar sözcüğü yoktur. statik final sabitleri nasıl bildirdiğinizdir.
Amir Afghani

5
Java 8'den beri bir uygulama içerebilirler, ancak backwarts uyumluluğuna ihtiyacınız yoksa kullanmamanız şiddetle tavsiye edilir. :)
codepleb

6
public interface A{
    int x=65;
}
public interface B{
    int x=66;
}
public class D implements A,B {
    public static void main(String[] a){
        System.out.println(x); // which x?
    }
}

İşte çözüm.

System.out.println(A.x); // done

Arayüz değişkeninin statik olmasının bir nedeni olduğunu düşünüyorum.

Arayüz içindeki değişkenleri bildirmeyin.


3
Aslında, "Axe" spesifikasyonu olmadan bile derlemezdi, bu yüzden arayüzlerde değişkenleri (dolaylı olarak halka açık statik final) kullanmak güvenlidir
Marco

@Marco'nun derlemeyeceğini bile söylediği gibi cevaba katılmıyorum. Şimdiye kadar başka bir dezavantaj bulamadım, belki de static finalaslında statik ve nihai değişkenten önce yazılı görmüyorsunuz .
Micer

5

static - çünkü Arayüz herhangi bir örneğe sahip olamaz. ve son olarak - değiştirmemiz gerekmiyor.


15
"ihtiyacımız yok" == "izin verilmez", anlamları karıştırmayın.
peterh - Monica Mar'ı

3

Çünkü:

Static : arayüzlerin nesnelerine sahip olamayacağımızdan, Object level üye değişkenlerini kullanmaktan kaçınmalı ve class level değişkenlerini yani static kullanmalıyız.

Final : Değişkenler için belirsiz değerler olmamalıdır (Elmas problemi - Çoklu Kalıtım).

Ve dokümantasyon arayüzüne göre bir uygulama değil, bir sözleşmedir.

referans: Abhishek Jain'in quora'daki cevabı


2

Java, arabirimlerde soyut değişkenlere ve / veya yapıcı tanımlarına izin vermez. Çözüm: Arayüzünüzle uygulamanız arasında yalnızca soyut sınıfı genişleten soyut bir sınıf asın:

 public interface IMyClass {

     void methodA();
     String methodB();
     Integer methodC();

 }

 public abstract class myAbstractClass implements IMyClass {
     protected String varA, varB;

     //Constructor
     myAbstractClass(String varA, String varB) {
         this.varA = varA;
         this.varB = VarB;
     }

     //Implement (some) interface methods here or leave them for the concrete class
     protected void methodA() {
         //Do something
     }

     //Add additional methods here which must be implemented in the concrete class
     protected abstract Long methodD();

     //Write some completely new methods which can be used by all subclasses
     protected Float methodE() {
         return 42.0;
     }

 }

 public class myConcreteClass extends myAbstractClass {

     //Constructor must now be implemented!
     myClass(String varA, String varB) {
         super(varA, varB);
     }

     //All non-private variables from the abstract class are available here
     //All methods not implemented in the abstract class must be implemented here

 }

Daha sonra diğer arabirimlerle birlikte uygulamak istemediğinizden EMİN iseniz, herhangi bir arabirim olmadan soyut bir sınıf da kullanabilirsiniz . Lütfen soyut bir sınıfın örneğini oluşturamayacağınızı ve önce onu genişletmeniz gerektiğini unutmayın.

("Korumalı" anahtar kelime, yalnızca genişletilmiş sınıfların bu yöntemlere ve değişkenlere erişebileceği anlamına gelir.)

spyro



1

Arayüz: Sistem gereksinimi hizmeti.

Arabirimde, değişken varsayılan olarak genel, statik, son erişim değiştirici tarafından atanır . Çünkü :

public: Arayüzün başka bir pakete yerleştirilmesi bazen olabilir. Bu nedenle, değişkenin projenin herhangi bir yerinden erişmesi gerekir.

statik: Böyle eksik bir sınıf nesne oluşturamaz. Bu yüzden projede değişkene nesne olmadan erişmemiz gerekiyor, böyleceinterface_filename.variable_name

final: Bir sınıfın birçok sınıf tarafından uygulandığını ve tüm sınıfların arayüz değişkenine erişmeye ve bunları güncellemeye çalıştığını varsayalım. Böylece veri değişiminde tutarsızlığa yol açar ve diğer tüm sınıfları etkiler. Bu yüzden erişim değiştiriciyi final ile bildirmek gerekir.


0

İçinde Java, arayüz herhangi bir örnek değişkeni bildirmenize izin vermez. Bir arabirimde bildirilen bir değişkenin örnek değişkeni olarak kullanılması, bir derleme zamanı hatası döndürür.

static finalBir örnek değişkeninden farklı olan sabit değişkeni bildirebilirsiniz .


Bu çok yanlış. Özel veya korumalı olmadıkça derleyici şikayet etmeyecektir. Kaputun altında, diğerlerinin de belirttiği gibi, genel statik finale dönüştürülürler. Ve sanırım neden oldukça açık. Çünkü arayüz, durumu değil, davranışı dikte etmek içindir.
Mikayil Abdullayev

0

Arayüz herhangi bir sınıf tarafından uygulanabilir ve bu değer orada uygulayıcı sınıflardan biri tarafından değiştirilirse, diğer uygulayıcı sınıflar için yanıltıcı olur. Arayüz temel olarak iki çekirdeklenmiş ancak farklı varlığı birleştirmek için bir referanstır. Bu nedenle arayüz içindeki bildirme değişkeni dolaylı olarak nihai ve ayrıca statik olacaktır çünkü arayüz anlık olamaz.


0

Arayüz tanımlı ve diğer sınıfların uyguladığı bir web uygulamasını düşünün. Değişkenlere erişmek için bir arabirim örneği oluşturamadığınız için statik bir anahtar kelimeye sahip olmanız gerekir. Statik olduğundan, değerdeki herhangi bir değişiklik, onu uygulayan diğer örnekleri yansıtacaktır. Bunu önlemek için onları nihai olarak tanımlarız.


0

Eclipse'de yeni denedim, arayüzdeki değişken varsayılan olarak sondur, bu yüzden değiştiremezsiniz. Üst sınıfla karşılaştırıldığında, değişkenler kesinlikle değiştirilebilir. Neden? Benim açımdan, sınıftaki değişken, çocuklar tarafından miras alınacak bir özelliktir ve çocuklar bunu gerçek ihtiyaçlarına göre değiştirebilir. Aksine, arayüz nitelik değil, sadece davranışı tanımlar. Arabirimde değişkenleri koymanın tek nedeni, onları bu arabirimle ilgili sabitler olarak kullanmaktır. Yine de, aşağıdaki alıntıya göre bu iyi bir uygulama değildir:

"Sabitleri bir arayüze yerleştirmek, Java'nın ilk günlerinde popüler bir teknikti, ancak şimdi birçok kişi bunu arayüzlerin tatsız bir kullanımı olarak görüyor, çünkü arayüzler, verileri değil, bir nesnenin sağladığı hizmetler ile ilgilenmelidir. bir sınıf, genellikle bir uygulama ayrıntısıdır, ancak bunları bir arayüze yerleştirmek onları sınıfın genel API'sına yükseltir. "

Ben de statik koymak ya da hiç fark etmez denedim. Kod aşağıdaki gibidir:

public interface Addable {
    static int count = 6;

    public int add(int i);

}

public class Impl implements Addable {

    @Override
    public int add(int i) {
        return i+count;
    }
}

public class Test {

    public static void main(String... args) {
        Impl impl = new Impl();

        System.out.println(impl.add(4));
    }
}
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.