1. Yetenekler

Arayüzlerin faydalarını ve nerelerde kullanılacağını daha iyi anlamak için biraz daha soyut şeylerden bahsetmemiz gerekiyor.

Bir sınıf genellikle belirli bir nesneyi modeller. Bir arayüz, nesnelere daha az, yeteneklerine veya rollerine daha çok karşılık gelir.

Arayüzlerin özü

Örneğin, arabalar, bisikletler, motosikletler ve tekerlekler gibi şeyler en iyi şekilde sınıflar ve nesneler olarak temsil edilir. Ancak yetenekleri - "Ben binebilirim", "İnsanları taşıyabilirim", "Ayakta durabilirim" gibi - arayüzler olarak daha iyi sunulur. İşte bazı örnekler:

kod Tanım
interface CanMove
{
   void move(String newLocation);
}
Hareket etme yeteneğine karşılık gelir
interface Rideable
{
   void ride(Passenger passenger);
}
Binilme yeteneğine karşılık gelir
interface CanTransport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
Eşya taşıma yeteneğine karşılık gelir
class Wheel implements CanMove
{
   ...
}
sınıf hareketWheel edebilir
class Car implements CanMove, Rideable, CanTransport
{
   ...
}
Sınıf hareket Caredebilir , binilebilir ve bir şeyler taşıyabilir
class Skateboard implements CanMove, Rideable
{
   ...
}
Sınıf hareket Skateboardedebilir ve basılabilir


2. Roller

Arayüzler, bir programcının hayatını büyük ölçüde basitleştirir. Çoğu zaman, bir program binlerce nesneye, yüzlerce sınıfa sahiptir, ancak yalnızca birkaç düzine arabirime , yani rollere sahiptir . Birkaç rol vardır, ancak bunları (sınıfları) birleştirmenin birçok yolu vardır.

Bütün mesele şu ki, diğer tüm sınıflarla etkileşime geçmek için her sınıfa kod yazmak zorunda değilsiniz. Sadece rolleri (arayüzleri) ile etkileşime geçmeniz gerekir.

Bir evcil hayvan eğitmeni olduğunuzu hayal edin. Çalıştığınız evcil hayvanların her birinin birkaç farklı yeteneği olabilir. Komşunuzla kimin evcil hayvanının en çok ses çıkarabileceği konusunda dostça bir tartışmaya girersiniz. Sorunu çözmek için, "konuşabilen" tüm evcil hayvanları sıraya koyun ve onlara şu komutu verin: Konuşun!

Ne tür bir hayvan oldukları veya başka hangi yeteneklere sahip oldukları umrunda değil. Üçlü geri takla yapabilseler bile. Şu anda, yalnızca yüksek sesle konuşma yetenekleriyle ilgileniyorsunuz. İşte kodda nasıl görüneceği:

kod Tanım
interface CanSpeak
{
   void speak();
}
yetenek CanSpeak. Bu arabirim to komutunu anlar speak, yani karşılık gelen bir yöntemi vardır.
class Cat implements CanSpeak
{
   void speak()
   {
      println("MEOW");
   }
}

class Dog implements CanSpeak
{
   void speak()
   {
      println("WOOF");
   }
}

class Fish
{
   ...
}
Bu özelliğe sahip hayvanlar.

Anlamayı kolaylaştırmak için sınıf adlarını İngilizce olarak verdik. Buna Java'da izin verilir, ancak son derece istenmeyen bir durumdur.













Bizim Fishkonuşma yeteneğimiz yok (arayüz uygulamıyor CanSpeak).

public static void main(String[] args)
{
   // Add all the animals to the list
   ArrayList pets = new ArrayList();
   pets.add(new Cat());
   pets.add(new Dog());
   pets.add(new Fish());

   // If the ability exists, then make a sound
   for(Object pet: pets)
   {
      if (pet instanceof CanSpeak)
      {
         CanSpeak loudmouth = (CanSpeak) pet;
         loudmouth.speak();
      }
   }
}
Ve onlara komutu nasıl veririz?

Programlarınızdaki sınıf sayısı binleri bulduğunda arayüzsüz yaşayamayacaksınız. Binlerce sınıfın etkileşimini tanımlamak yerine, birkaç düzine arayüzün etkileşimini tanımlamak yeterlidir - bu, hayatı büyük ölçüde kolaylaştırır.

Ve polimorfizmle birleştiğinde, bu yaklaşım genellikle büyük bir başarıdır.



3. defaultArayüz yöntemlerinin uygulanması

Soyut sınıflar, değişkenlere ve yöntem uygulamalarına sahip olabilir, ancak birden çok kalıtıma sahip olamazlar. Arabirimler, değişkenlere veya yöntem uygulamalarına sahip olamaz, ancak birden fazla kalıtıma sahip olabilir.

Durum aşağıdaki tabloda ifade edilmektedir:

Yetenek/özellik Soyut sınıflar arayüzler
Değişkenler
Yöntem uygulaması
çoklu kalıtım

Bu nedenle, bazı programcılar gerçekten arabirimlerin yöntem uygulamalarına sahip olma becerisine sahip olmasını istediler. Ancak, bir yöntem uygulaması ekleme yeteneğine sahip olmak, bir yöntemin her zaman ekleneceği anlamına gelmez. İsterseniz ekleyin. Ya da yapmazsan, yapma.

Ek olarak, çoklu kalıtımla ilgili problemler öncelikle değişkenlerden kaynaklanmaktadır. Her halükarda, karar verdikleri ve yaptıkları buydu. JDK 8 ile başlayan Java, arayüzlere yöntem uygulamaları ekleme yeteneğini tanıttı.

İşte güncellenmiş bir tablo (JDK 8 ve üstü için):

Yetenek/özellik Soyut sınıflar arayüzler
Değişkenler
Yöntem uygulaması
çoklu kalıtım

Artık soyut sınıflar ve arabirimler için, uygulamalı veya uygulamasız yöntemler bildirebilirsiniz. Ve bu harika bir haber!

Soyut sınıflarda, uygulaması olmayan yöntemlerden önce anahtar kelime gelmelidir abstract. Bir uygulama ile metotlardan önce herhangi bir şey eklemenize gerek yoktur. Arayüzlerde bunun tersi doğrudur. Bir yöntemin uygulaması yoksa, hiçbir şey eklenmemelidir. Ancak bir uygulama varsa, o zaman defaultanahtar kelime eklenmelidir.

Basit olması için, bu bilgiyi aşağıdaki küçük tabloda sunuyoruz:

Yetenek/özellik Soyut sınıflar arayüzler
Uygulaması olmayan yöntemler abstract
Uygulamalı yöntemler default

Sorun

Yöntemleri olan arabirimleri kullanmak, büyük sınıf hiyerarşilerini büyük ölçüde basitleştirebilir. Örneğin, özet InputStreamve OutputStreamsınıflar arayüz olarak bildirilebilir! Bu, onları çok daha sık ve çok daha rahat kullanmamızı sağlar.

Ancak dünyada zaten on milyonlarca (milyarlarca?) Java sınıfı var. Ve standart kitaplıkları değiştirmeye başlarsanız, bir şeyleri bozabilirsiniz. Herşey gibi! 😛

Mevcut programları ve kütüphaneleri yanlışlıkla bozmamak için, arayüzlerdeki metot uygulamalarının kalıtım önceliği en düşük olmasına karar verildi .

Örneğin, bir arabirim yöntemi olan başka bir arabirimi miras alırsa ve ilk arabirim aynı yöntemi bir uygulama olmadan bildirirse, miras alınan arabirimden yöntem uygulaması devralan arabirime ulaşmayacaktır. Örnek:

interface Pet
{
   default void meow()
   {
      System.out.println("Meow");
   }
}

interface Cat extends Pet
{
   void meow(); // Here we override the default implementation by omitting an implementation
}

class Tom implements Cat
{
}

TomSınıf yöntemi uygulamadığından kod derlenmeyecek meow().