Nesne yönelimli programlamada "arayüz" tanımı nedir?


108

Tamam, bir arkadaşım programlamada "arayüzün" ne anlama geldiğini ileri geri söylüyor.

Bir "arayüz" ün en iyi tanımı nedir.

Bana göre bir arayüz bir sınıfın bir planıdır, bu en iyi tanım mıdır?


1
dupe değil, ancak bu soruya çok ışık tutuyor: stackoverflow.com/questions/444245/…
rmeador

Genel bir kelime olduğunu söyleyebilirim ama benim için hala aynı anlama geliyor. Bu, belirli veya daha soyut bir varlık için, dışarıya bazı girdi noktaları sağlayan ve onlara herhangi bir iç işlem bilgisi olmadan çıktı veren bir duvar gibidir. OOP'de alt ve üst düzey sınıfları tanımlamak için bir soyutlama olarak adlandırılabileceğini düşünüyorum.
ikbal

Yanıtlar:


180

Arayüz, geliştirmede en fazla aşırı yüklü ve kafa karıştırıcı terimlerden biridir.

Aslında bir soyutlama ve kapsülleme kavramıdır. Belirli bir "kutu" için, bu kutunun " girişlerini" ve "çıkışlarını" bildirir . Yazılım dünyasında, bu genellikle kutuda çağrılabilen işlemler (argümanlarla birlikte) ve bazı durumlarda bu işlemlerin dönüş türleri anlamına gelir.

Yapmadığı şey, bu işlemlerin anlamlarının ne olduğunu tanımlamaktır, ancak bunları bildirime yakın olarak belgelemek (örneğin, yorumlar yoluyla) veya iyi adlandırma kurallarını seçmek sıradan (ve çok iyi bir uygulamadır). Yine de, bu niyetlerin yerine getirileceğine dair hiçbir garanti yoktur.

İşte bir benzetme: Kapalıyken televizyonunuza bir göz atın. Arayüzü, sahip olduğu düğmeler, çeşitli fişler ve ekrandır. Anlamsallığı ve davranışı, girişleri alması (örneğin, kablo programlama) ve çıkışlara (ekranda görüntü, ses vb.) Sahip olmasıdır. Ancak, prize takılı olmayan bir TV'ye baktığınızda, beklenen anlam bilginizi bir arayüze yansıtırsınız. Bildiğiniz tek şey, televizyonu prize taktığınızda patlayabilir. Ancak, "arayüzüne" dayanarak su girişi olmadığı için kahve yapmayacağını varsayabilirsiniz.

Nesne yönelimli programlamada, bir arabirim genellikle bu arabirime sahip bir sınıf örneğinin yanıt verebileceği yöntemler (veya mesajlar) kümesini tanımlar.

Karışıklığa katkıda bulunan şey, Java gibi bazı dillerde, dile özgü anlambilimiyle gerçek bir arayüzün olmasıdır. Örneğin Java'da, uygulaması olmayan bir yöntem bildirimleri kümesidir, ancak bir arabirim de bir türe karşılık gelir ve çeşitli yazım kurallarına uyar.

C ++ gibi diğer dillerde arayüzlere sahip değilsiniz. Bir sınıfın kendisi yöntemleri tanımlar, ancak sınıfın arayüzünü özel olmayan yöntemlerin bildirimleri olarak düşünebilirsiniz. C ++ 'ın nasıl derlendiği nedeniyle, gerçek uygulama olmadan sınıfın "arabirimine" sahip olabileceğiniz başlık dosyalarını alırsınız. Ayrıca saf sanal işlevlere sahip soyut sınıflarla Java arayüzlerini de taklit edebilirsiniz.

Bir arayüz, kesinlikle bir sınıf için bir plan değildir. Bir plan, bir tanıma göre "ayrıntılı bir eylem planıdır". Bir arayüz, bir eylem hakkında hiçbir şey vaat etmez! Karışıklığın kaynağı, çoğu dilde, bir dizi yöntemi tanımlayan bir arabirim türüne sahipseniz, onu uygulayan sınıfın aynı yöntemleri "yinelemesi" (ancak tanım sağlar), dolayısıyla arabirimin bir iskelet veya bir iskelet gibi görünmesidir. sınıfın ana hatları.


Objective-C üzerine bir kitap okuyorum ve bana öyle geliyor ki yazarlar "protokol" ve "arayüz" terimlerini birbirinin yerine kullanıyorlar. "Protokol" ve "arayüz" ün aynı şey olduğunu söylemek doğru mu yoksa bir şey mi kaçırıyorum?
Fazzolini

1
"Arayüz" için "protokol" kelimesini kullanmazdım. "Protokol" kelimesi, eylemlerin nasıl gerçekleştirildiğine dair bir ayrıntı düzeyini ifade eder. "Arayüz" gerçekten, tam olarak ne olduğunu kesin bir şekilde açıklayan saf bir İngilizce tanımına sahip mükemmel bir kelimedir.
OCDev

Windows programlama arayüzleri oldukça yaygın olarak kullanılmaktadır, bu nedenle C ++ 'da bile "arayüzler" ile uygulamadan ayrıştırılmış nesneler şeklinde karşılaşabilirsiniz.
Victoria

166

Şu durumu düşünün:

Bir zombi aniden size saldırdığında geniş, boş bir odanın ortasındasınız.

Silahın yok.

Neyse ki, yaşayan bir insan, odanın kapısında duruyor.

"Hızlı!" ona bağırıyorsun. "Bana zombiye vurabileceğim bir şey fırlat!"

Şimdi düşünün: Arkadaşınızın
tam olarak ne atmayı seçeceğini belirtmediniz (ne de umursamıyorsunuz) ;
... Ama şu sürece önemli değil:

  • It adlı bir şeyler olabilir atmış (Sana kanepe atmak olamaz)

  • Bu tutabileceğin bir şey (Umarım bir shuriken atmamıştır)

  • Bu, zombinin beynini kırmak için kullanabileceğiniz bir şey (Bu, yastık ve benzeri şeyleri dışlar)

Bir beyzbol sopası veya çekiç almanız fark etmez -
üç koşulunuzu yerine getirdiği sürece iyisinizdir.

Özetlersek:

Bir arayüz yazdığınızda, temel olarak "Bir şeye ihtiyacım var ..." diyorsunuz.


13
Aslında yastık yine de işe yarar. Onunla zombiye vurabilirsin. Zombinin beynini sıkıştırın ... bu bir performans meselesidir, bu asla arayüzün bir parçası değildir.
meustrus

35

Arayüz, uygulayıcı veya kullanıcı olmanıza bağlı olarak uymanız veya vermeniz gereken bir sözleşmedir.


1
Aslında buradaki şartsız sözleşmeyi sevmiyorum, çünkü bir sözleşme genellikle anlambilim veya davranış anlamına gelir (sözleşmeye göre tasarımda olduğu gibi). Tüm arayüzler herhangi bir anlam veya davranış içermez. Örneğin, "duvardaki bir delik" gerçek dünya arayüzüdür. Bunu bir pencere olarak veya çöp öğütücüsü olarak veya herhangi bir şey olarak algılamanız sizin yorumunuzdur.
Uri

3
Doğru. Arayüz bir "yöntem imza sözleşmesidir", yani verilen yöntemlerin uygulanmasını garanti eder. Herhangi bir şekilde yapıp yapmadığına dair hiçbir garanti vermez.
Erik Funkenbusch

Kesinlikle, bu tanıma daha fazla açıklama yapmalısınız. Ancak bir arayüz, iki parça arasındaki bir sözleşmedir. Sözleşmeye göre kod .... +1
matiasnj

18

Planın kullanmak için iyi bir kelime olduğunu sanmıyorum. Bir plan size bir şeyi nasıl inşa edeceğinizi söyler. Bir arayüz özellikle size bir şeyi nasıl inşa edeceğinizi söylemekten kaçınır.

Bir arayüz, bir sınıfla nasıl etkileşim kurabileceğinizi, yani hangi yöntemleri desteklediğini tanımlar.


1
İstekte bulunanın, tanımın ne olmadığını sorduğuna inanıyorum. :)
Eugene Kuleshov

7

Bana göre bir arayüz bir sınıfın bir planıdır, bu en iyi tanım mıdır?

Hayır. Plan tipik olarak iç kısımları içerir. Ancak bir arayüz, tamamen bir sınıfın dışında görünen şeyle ilgilidir ... veya daha doğrusu, arayüzü uygulayan bir sınıflar ailesi.

Arayüz, sabitlerin yöntemlerinin ve değerlerinin imzalarından ve ayrıca arayüzü uygulayan sınıflar ve onu kullanan diğerleri arasında (tipik olarak gayri resmi) bir "davranışsal sözleşme" içerir.


6

Programlamada bir arayüz, bir nesnenin sahip olacağı davranışı tanımlar, ancak aslında davranışı belirtmez. Bu, belirli bir sınıfın bir şeyler yapabileceğini garanti edecek bir sözleşmedir.

Bu C # kodunu burada düşünün:

using System;

public interface IGenerate
{
    int Generate();
}

// Dependencies
public class KnownNumber : IGenerate
{
    public int Generate() 
    {
        return 5;
    }   
}

public class SecretNumber : IGenerate
{
    public int Generate()
    {
        return new Random().Next(0, 10);
    }
}

// What you care about
class Game
{
    public Game(IGenerate generator) 
    {
        Console.WriteLine(generator.Generate())
    }
}

new Game(new SecretNumber());
new Game(new KnownNumber());

Oyun sınıfı gizli bir numara gerektirir. Bunu test etmek için, gizli numara olarak kullanılacak olanı enjekte etmek istersiniz (bu ilkeye Kontrolün Ters Çevrilmesi adı verilir).

Oyun sınıfı, rastgele sayıyı gerçekte neyin yaratacağı konusunda "açık fikirli" olmak ister, bu nedenle kurucusunda "Generate yöntemi olan herhangi bir şey" soracaktır.

İlk olarak arayüz, bir nesnenin hangi işlemleri sağlayacağını belirtir. Sadece neye benzediğini içerir, ancak gerçek bir uygulama verilmez. Bu sadece yöntemin imzasıdır. Geleneksel olarak, C # arayüzlerinde bir I öneki bulunur. Sınıflar artık IGenerate Arayüzünü uygular. Bu, derleyicinin her ikisinin de bir int döndüren ve çağrılan bir yönteme sahip olduğundan emin olacağı anlamına gelir Generate. Oyuna şimdi iki farklı nesne deniyor ve bunların her biri doğru arayüze sahip. Diğer sınıflar, kodu oluştururken bir hata üretebilir.

Burada, kullandığınız plan benzetmesini fark ettim:

Bir sınıf, genellikle bir nesnenin taslağı olarak görülür. Bir Arayüz, bir sınıfın yapması gereken bir şeyi belirtir, bu yüzden bunun bir sınıf için sadece bir taslak olduğu iddia edilebilir, ancak bir sınıfın mutlaka bir arayüze ihtiyacı olmadığı için, bu metaforun kırıldığını iddia ediyorum. Arayüzü bir sözleşme olarak düşünün. "İmzalayan" sınıfın sözleşmedeki hüküm ve koşullara uyması yasal olarak gerekli olacaktır (derleyici polisi tarafından zorunlu kılınacaktır). Bu, arayüzde belirtilenleri yapması gerektiği anlamına gelir.

Bu, Java veya C # ile olduğu gibi, bazı OO dillerinin statik olarak yazılmış doğasından kaynaklanmaktadır. Python'da ise başka bir mekanizma kullanılır:

import random

# Dependencies
class KnownNumber(object):
    def generate(self):
        return 5

class SecretNumber(object):
    def generate(self):
        return random.randint(0,10)

# What you care about
class SecretGame(object):
    def __init__(self, number_generator):
        number = number_generator.generate()
        print number

Burada, sınıfların hiçbiri bir arabirim uygulamaz. Python bunu umursamaz, çünkü SecretGamesınıf sadece geçirilen nesneyi çağırmaya çalışır. Nesne bir generate () yöntemine sahipse, her şey yolunda demektir. Olmazsa: KAPUTT! Bu hata derleme zamanında değil, çalışma zamanında, dolayısıyla muhtemelen programınız zaten konuşlandırılmış ve çalışırken görülecektir. Sen buna yaklaşmadan C # seni uyarırdı.

Bu mekanizmanın kullanılmasının nedeni, safça ifade edilir, çünkü OO dillerinde doğal olarak işlevler birinci sınıf vatandaş değildir. Gördüğünüz, gibi KnownNumberve SecretNumberbir sayı oluşturmak için SADECE işlevleri içerir. İnsanın derslere gerçekten ihtiyacı yok. Python'da, bu nedenle, biri onları bir kenara atabilir ve işlevleri kendi başlarına seçebilir:

# OO Approach
SecretGame(SecretNumber())
SecretGame(KnownNumber())

# Functional Approach

# Dependencies
class SecretGame(object):
    def __init__(self, generate):
        number =  generate()
        print number

SecretGame(lambda: random.randint(0,10))
SecretGame(lambda: 5)

Bir lambda, "ilerledikçe sırayla" bildirilen bir işlevdir. Temsilci, C # 'da aynıdır:

class Game
{
    public Game(Func<int> generate) 
    {
        Console.WriteLine(generate())
    }
}    

new Game(() => 5);
new Game(() => new Random().Next(0, 10));

Ek not: Son örnekler Java 7'ye kadar bunun gibi mümkün değildi. Orada, bu davranışı belirlemenin tek yolu Arabirimlerdi. Bununla birlikte, Java 8 lambda ifadelerini tanıttı, böylece C # örneği çok kolay bir şekilde Java'ya dönüştürülebilir ( Func<int>olur java.util.function.IntSupplierve =>olur ->).


4

Teknik olarak, bir arabirimi bir nesneyle etkileşime girmenin bir dizi yolu (yöntemler, özellikler, erişimciler ... kelime haznesi kullandığınız dile bağlıdır) olarak tanımlardım. Bir nesne bir arabirimi destekliyorsa / uyguluyorsa, bu nesneyle etkileşim kurmak için arabirimde belirtilen tüm yolları kullanabilirsiniz.

Anlamsal olarak, bir arayüz, ne yapıp yapamayacağınıza (örneğin, yöntemleri çağırabileceğiniz sıra) ve karşılığında, nasıl etkileşim kurduğunuza göre nesnenin durumu hakkında ne varsayabileceğinize dair kurallar da içerebilir. Irak.


2

Şahsen şablon gibi bir arayüz görüyorum. Bir arabirim foo () ve bar () yöntemlerinin tanımını içeriyorsa, bu arabirimi kullanan her sınıfın foo () ve bar () yöntemlerine sahip olduğunu bilirsiniz.


2

Bir Adamın (Kullanıcı veya Nesne) bazı işlerin yapılmasını istediğini düşünelim. Şirketlerle (uygulanan sınıflar kullanılarak oluşturulan gerçek dünya nesneleri) bir sözleşme yapacak olan bir aracı (Arayüz) ile iletişime geçecektir. Hangi şirketlerin uygulayacağı ve sonuç vereceği birkaç tür iş kendisi tarafından tanımlanacaktır. Her firma işi kendine göre uygulayacak ama sonuç aynı olacak. Bu Kullanıcı işini tek bir arayüz kullanarak yapacağı gibi. Arayüzün, uygulayan iç alt sistemler tarafından dahili olarak tanımlanacak birkaç komutla sistemlerin görünür bir parçası olarak hareket edeceğini düşünüyorum.


1

Bir arabirim, bir sınıftaki işlemleri içindeki uygulamadan ayırır. Bu nedenle, bazı uygulamalar birçok arayüz sağlayabilir.

İnsanlar bunu genellikle sınıfın yöntemlerinde bulunması gerekenler için bir "sözleşme" olarak tanımlarlar.

Kesinlikle bir plan değildir, çünkü bu aynı zamanda uygulamayı da belirleyecektir. Tam bir sınıf tanımının bir plan olduğu söylenebilir.


1

Bir arabirim, kendisinden miras alan bir sınıfın uygulaması gerektiğini tanımlar. Bu şekilde, birden çok sınıf bir arabirimden miras alabilir ve bu eylemsizlik nedeniyle,

  • Arayüzün tüm üyelerinin türetilmiş sınıfta uygulandığından emin olun (sadece bir istisna oluştursa bile)
  • Sınıfın kendisini çağırandan soyutlayın (bir sınıfın bir örneğini arayüze atın ve türetilmiş gerçek sınıfın ne olduğunu bilmeye gerek kalmadan onunla etkileşime geçin)

daha fazla bilgi için bu http://msdn.microsoft.com/en-us/library/ms173156.aspx adresine bakın.


1

Bana göre arayüz, Java'da yaygın olarak ilişkilendirilen arayüzden daha geniş bir anlama sahiptir. "Arayüzü", bir modülün kontrol edilmesine / izlenmesine olanak tanıyan bazı ortak işlevlere sahip bir dizi kullanılabilir işlem olarak tanımlardım.

Bu tanımda, hem istemcinin bir modül olduğu programatik arayüzleri hem de insan arayüzlerini (örneğin GUI) kapsamaya çalışıyorum.

Diğerlerinin daha önce de söylediği gibi, bir arayüzün arkasında her zaman girdi ve çıktılar açısından bir sözleşme vardır. Arayüz, işlemlerin "nasıl" olduğuna dair hiçbir şey vaat etmiyor; yalnızca mevcut durum, seçilen işlem ve parametreleri göz önüne alındığında sonucun bazı özelliklerini garanti eder.


1

Yukarıdaki gibi, "sözleşme" ve "protokol" eşanlamlıları uygundur.

Arayüz, bir sınıf tarafından ifşa edilmesini bekleyebileceğiniz yöntem ve özellikleri içerir.

Dolayısıyla, bir sınıf arabirimi Cheetos Baguygularsa, a'nın tıpkı diğerleri gibi davranmasını Chip Bagbeklemelisiniz . (Yani, yöntemi ortaya çıkarın vb.)Cheetos BagChip Bag.attemptToOpenWithoutSpillingEverywhere()


1

Geleneksel Tanım - Arayüz, onu uygulayan sınıf tarafından uygulanması gereken yöntemleri belirten bir sözleşmedir.

Arayüzün Tanımı zamanla değişti. Arayüzün yalnızca yöntem bildirimlerine sahip olduğunu mu düşünüyorsunuz? Peki ya statik son değişkenler ve Java 5'ten sonraki varsayılan tanımlamalar ne olacak?

Arayüzler Java'ya çoklu Miras ile ilgili Diamond problemi nedeniyle tanıtıldı ve aslında yapmayı amaçladıkları şey bu.

Arayüzler, çoklu kalıtım probleminden kurtulmak için oluşturulmuş yapılardır ve soyut yöntemlere, varsayılan tanımlara ve statik son değişkenlere sahip olabilir.

http://www.quora.com/Why-does-Java-allow-static-final-variables-in-interfaces-when-they-are-only-intended-to-be-contracts



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.