Java 8 statik arabirim yöntemlerine izin verir
Java 8 ile arayüzler olabilir statik yöntemler var. Ayrıca somut örnek yöntemlerine sahip olabilirler, ancak örnek alanlarına sahip olmayabilirler.
Burada gerçekten iki soru var:
- Neden kötü eski günlerde arayüzler statik yöntemler içeremedi?
- Statik yöntemler neden geçersiz kılınamıyor?
Arayüzlerde statik yöntemler
Önceki sürümlerde arabirimlerin statik yöntemlere sahip olamamasının güçlü bir teknik nedeni yoktu. Bu, yinelenen bir sorunun posteri ile güzel bir şekilde özetlenir . Statik arayüz yöntemleri başlangıçta küçük bir dil değişikliği olarak kabul edildi ve daha sonra bunları Java 7'ye eklemek için resmi bir teklif vardı , ancak daha sonra öngörülemeyen komplikasyonlar nedeniyle düştü.
Son olarak, Java 8, statik arabirim yöntemlerinin yanı sıra varsayılan bir uygulama ile geçersiz kılınabilir örnek yöntemlerini tanıttı. Yine de örnek alanları olamaz. 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ünde okuyabilirsiniz .
Statik yöntemleri geçersiz kılma
İkinci sorunun cevabı biraz daha karmaşıktır.
Statik yöntemler derleme zamanında çözülebilir. Dinamik dağıtım, ö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öntem çağırmak bir sınıf gerektirir ve bu sınıf statik olarak - derleme zamanında - bilindiği için dinamik gönderme gereksizdir.
Burada neler olduğunu anlamak için örnek yöntemlerinin nasıl çalıştığına dair biraz arka plan gereklidir. Gerçek uygulama oldukça farklı olduğundan eminim, ancak davranışları doğru bir şekilde gözlemlediğimiz model gönderme yöntemini açıklayayım.
Her sınıfın, yöntemi uygulamak için yöntem imzalarını (ad ve parametre türleri) gerçek bir kod yığınıyla eşleyen bir karma tablosu olduğunu varsayın. Sanal makine bir örnek üzerinde bir yöntemi çağırmaya çalıştığında, nesneyi sınıfı için sorgular ve sınıfın tablosunda istenen imzayı arar. Bir yöntem gövdesi bulunursa çağrılır. Aksi takdirde, sınıfın üst sınıfı elde edilir ve arama burada tekrarlanır. Bu, yöntem bulunana kadar veya başka ana sınıf kalmayana kadar devam eder - bu da a sonucunu verir NoSuchMethodError
.
Üst sınıf ve alt sınıfların her ikisi de tablolarında aynı yöntem imzası için bir giriş içeriyorsa, ö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 sunar. Ancak, derleyici zamanında tüm olabilir, çünkü derleyici kendi sınıfı için belirtilmemiş türde bir nesneyi sorgulamak için çalışma zamanını beklemek yerine bilinen bir sınıftan başlar. İstenen sürümü içeren sınıfı her zaman belirtebildiğinden, statik bir yöntemi "geçersiz kılmanın" bir anlamı yoktur.
Yapıcı "arayüzler"
İşte soruya yönelik son düzenlemeyi ele almak için biraz daha malzeme.
Her uygulaması için etkili bir yapıcı benzeri bir yöntem uygulamak istediğiniz gibi görünüyor IXMLizable
. Bir dakika boyunca bunu bir arayüzle uygulamaya çalışmayı unutun ve bu gereksinimi karşılayan bazı sınıflarınız olduğunu varsayalım. Nasıl kullanırdın?
class Foo implements IXMLizable<Foo> {
public static Foo newInstanceFromXML(Element e) { ... }
}
Foo obj = Foo.newInstanceFromXML(e);
Foo
Yeni nesneyi "oluştururken" somut türü açıkça adlandırmanız gerektiğinden, derleyici gerçekten gerekli fabrika yöntemine sahip olduğunu doğrulayabilir. Ve değilse, ne olacak? Bir uygulamaya Eğer IXMLizable
"yapıcı" yoksun olduğunu, ve ben bir örneğini oluşturmak ve kod geçmek, bu ise bir IXMLizable
gerekli tüm arayüz ile.
İnşaat, arayüzün değil uygulamanın bir parçasıdır . Arabirimle başarıyla çalışan herhangi bir kod yapıcıyı önemsemez. Yapıcıya önem veren herhangi bir kodun zaten beton türünü bilmesi gerekir ve arayüz göz ardı edilebilir.