Arayüzler neden faydalıdır?


158

Bir süredir C # da okuyordum ve kodluyorum. Ancak yine de, Arayüzlerin kullanışlılığını çözemiyorum. Masaya çok az getiriyorlar. İşlev imzalarını sağlamaktan başka hiçbir şey yapmazlar. Uygulanması gereken işlevlerin adlarını ve imzasını hatırlayabilirsem, onlara gerek yoktur. Söz konusu işlevlerin (arayüzde) miras sınıfında yerine getirildiğinden emin olmak için vardırlar.

C # harika bir dil, ancak bazen size Microsoft'un sorunu yarattığı (çoklu kalıtıma izin vermeyen) ve daha sonra oldukça sıkıcı olan bir çözüm sunuyor.

Sınırlı kodlama deneyimine dayanan anlayışım bu Arayüzlere ne dersin? Onlardan ne sıklıkta faydalanıyorsunuz ve ne yapıyorsunuz?


55
"Uygulanması gereken işlevlerin adlarını ve imzasını hatırlayabilirsem, onlara gerek yoktur." Bu ifade , statik olarak yazılmış dillerin avantajlarına biraz daha fazla bakmanız gerektiğinden şüphelenmemi sağlıyor .
Steven Jeuris

37
C # unut, Java'yı unut, dili unut. OO açısından basitçe düşünüyor. Düşüncenizi genişletmenize yardımcı olacağı için Robert C. Martin, Martin Fowler, Michael Feathers, Dörtlü Çete gibi insanlardan bazı okuma materyalleri almanızı tavsiye ederim.
Anthony Pegram

27
Arayüzlerin neye iyi geldiğini gerçekten anlamam iki yıldan fazla sürdü. Önerim: Tasarım Desenlerini incelemek. Birçoğu arayüzlere dayandığından, neden bu kadar faydalı olduklarını çabucak anlayacaksınız.
Oliver Weiler

37
Arkadaşını öğrenecek çok şeyin var.
ChaosPandion 14:11

60
@ChaosPandion hepimiz öğrenecek çok şeyimiz var
kenwarner 14:01

Yanıtlar:


151

Söz konusu işlevlerin (arayüzde) miras sınıfında yerine getirildiğinden emin olmak için vardırlar.

Doğru. Bu özelliği haklı çıkarmak için yeterince harika bir avantaj. Diğerlerinin dediği gibi, bir arayüz belirli yöntemleri, özellikleri ve olayları uygulamak için sözleşmeye bağlı bir zorunluluktur . Statik olarak yazılmış bir dilin zorlayıcı faydası, derleyicinin, kodunuzun dayandığı bir sözleşmenin gerçekten karşılandığını doğrulayabilmesidir.

Bununla birlikte, arayüzler, sözleşmeden doğan yükümlülükleri temsil etmek için oldukça zayıf bir yoldur. Sözleşme yükümlülüklerini yerine getirmek için daha güçlü ve daha esnek bir yol istiyorsanız, Visual Studio'nun son sürümüyle birlikte verilen Kod Sözleşmeleri özelliğine bakın.

C # harika bir dil, ancak bazen size ilk önce Microsoft'un sorunu yarattığı (çoklu kalıtıma izin vermeyen) ve daha sonra oldukça sıkıcı olan bir çözüm sunuyor.

Peki sevdiğine sevindim.

Tüm karmaşık yazılım tasarımları, birbiriyle çelişen özelliklerin tartılmasının ve küçük maliyetler için büyük faydalar sağlayan "tatlı noktayı" bulmaya çalışmanın bir sonucudur. Uygulama deneyimi için çoklu mirasa izin veren dillerin nispeten küçük faydalara ve nispeten büyük maliyetlere sahip olduğunu acı verici bir deneyim aracılığıyla öğrendik . Yalnızca uygulama ayrıntılarını paylaşmayan arabirimlerde çoklu mirasa izin vermek, maliyetlerin çoğu olmadan çoklu mirasın birçok faydasını sağlar.


Sadece "Microsoft'un çoklu mirasa izin vererek sorunu yaratmadığını" okuyordum ve Eric Lippert'in bunun hakkında söyleyecek bir şeyleri olacağını düşündüm.
konfigüratör,

Bu cevapla daha alakalı: Eric, sorguyu Kod Sözleşmelerine havale ediyorsunuz, ancak bunlar tamamen eksik; En temel sözleşmelerden başka hiçbir şey statik denetleyici tarafından uygulanamaz. Küçük bir projede Kod Sözleşmesini kullanmayı denedim; Girdi ve çıktıyla ilgili yapabileceğim her şeyi belirten her yöntem için yüzlerce satır ekledim, ancak Assumedizi veya numaralandırma üyeleri gibi durumlar için çok fazla çağrı eklemek zorunda kaldım . Her şeyi ekledikten ve sahip olduğum statik olarak doğrulanmış karmaşayı gördükten sonra, projemin kalitesini düşürdüğü için kaynak kontrolüne geri döndüm.
konfigüratör

17
@configurator: Eksikler çünkü tamamlanamıyorlar; İsteğe bağlı sözleşmelerle yapılan statik program doğrulaması, Halting Problemini çözmeye eşdeğerdir. (Örneğin, bir yönteme ilişkin argümanların Fermat'ın Son Teoremine karşı bir örnek olması gerektiğini söyleyen bir kod sözleşmesi yazabilirsiniz; ancak statik doğrulayıcı böyle bir argüman olmadığını doğrulayamayacak.) Statik doğrulayıcının evrenin sıcak ölümünden önce çalışmalarını tamamlamasını beklerseniz, mantıklı bir şekilde kullanmalısınız. (Şikayetiniz BCL'nin yeterince açıklamamış olması durumunda: Katılıyorum.)
Eric Lippert

2
Bir yöntem, results dizisinin veya numaralandırmanın null içermediğini vaat ettiğinde, use yönteminin değerleri null değerine izin vermeyen yerlerde kullanabileceğini fark etmesini bekliyorum. Yapmamasını beklediğim tek şey bu değildi ve onsuz kullanılabilir olmak çok önemliydi; başka bir şey sadece bir bonus. Bununla birlikte, statik doğrulamanın tamamlanamayacağını biliyorum, bu yüzden sözleşmelere güvenmenin iyi bir alternatif olmadığını düşünüyorum.
konfigüratör

9
+1 "Peki sevdiğine sevindim." Ve diğer tüm şeyler de.
Robert S.

235

görüntü tanımını buraya girin

Yani bu örnekte, PowerSocket diğer nesneler hakkında başka hiçbir şey bilmiyor. Nesnelerin tümü PowerSocket tarafından sağlanan Gücüne bağlıdır, bu yüzden IPowerPlug'u uygularlar ve böylece ona bağlanabiliyorlar.

Arabirimler yararlıdır çünkü nesnelerin birbirleriyle ilgili başka hiçbir şey bilmeden birlikte çalışmak için kullanabilecekleri sözleşmeler sağlarlar.


4
Sol alt nesne IPowerPlug uygular gibi görünmüyor =)
Steven Striga

100
Kahretsin, ancak IPowerPlug'u farklı ülkelerde kullanmak için bir Adaptör deseni kullanmamız gerekecek!
Steven Jeuris

Arayüzde çalışacak bir cihazı Jerry-arma yapmak güvenli değildir (ancak bazı insanlar hala test edilmemiş bir bahane olarak performansa atıfta bulunur) ve muhtemelen yangına yol açabilir.
YoungJohn,

4
Bu cevap sadece şaşırtıcı ...
Mario Garcia

Sadece bu cevabı işaret etmek - bu özel örnekte - neden bir arabirim kullanmak kalıtımsallıktan daha fazla tercih edilir? Arabirimler için yeni olan biri neden hepsinin neden yalnızca devralmadığını sorabilir, örneğin tüm fiş işlevlerini sağlayan MainsPoweredDevice'den, soket MainsPoweredDevice'den türetilen herhangi bir şeyi kabul ettiği için.
ingredient_15939

145

İşlev imzalarını sağlamaktan başka hiçbir şey yapmazlar. Uygulanması gereken fonksiyonların adlarını ve imzasını hatırlayabilirsem, onlara gerek yok

Arabirimlerin amacı, hangi yöntemi uygulayacağınızı hatırlamanıza yardımcı olmamakta, burada bir sözleşme tanımlamakta . Gelen foreach P.Brian.Mackey örneğin (ki yanlış olduğu ortaya çıkıyor , ama umurumuzda değil), IEnumerable arasındaki bir sözleşme tanımlar foreach ve herhangi enumerable şey. Diyor ki: "Her kimseniz, sözleşmeye sadık kaldığınız sürece (sayısız uygulayın), size tüm unsurlarınız üzerinde yineleme yapacağım söz veriyorum. Ve bu harika (dinamik olmayan bir dil için).

Arayüzler sayesinde iki sınıf arasında çok düşük eşleşme sağlayabilirsiniz.



"Ördek yazarak" terimini kullanmaktan hoşlanmıyorum çünkü farklı insanlara farklı şeyler ifade ediyor. "Foreach" döngüsü için kalıp eşleştirme kullanıyoruz, çünkü tasarlandığında IEnumerable <T> kullanılamıyordu. LINQ için kalıp eşleştirme kullanıyoruz, çünkü C # tipi sistem ihtiyacımız olan "monad kalıp" ı yakalamak için çok zayıf; Haskell tipi sistem gibi bir şeye ihtiyacınız olacak.
Eric Lippert 15:11

@Eric: "Desen eşleştirme" aynı sorunu yaşamıyor mu? Bunu duyduğumda sanırım F # / Scala / Haskell. Ama sanırım ördek yazmaya göre daha geniş bir fikir.
Daniel

@Daniel: Evet, sanırım öyle. Sanırım altıda biri diğerinden yarım düzine sanırım!
Eric Lippert

36

Arayüzler, iyi ayrışmış yapıları korumanın en iyi yoludur.

Test yazarken, somut sınıfların test ortamınızda çalışmayacağını göreceksiniz.

Örnek: Veri Erişim Hizmeti sınıfına bağlı bir sınıfı test etmek istiyorsunuz . Bu sınıf bir web servisiyle veya veritabanıyla konuşuyorsa - birim testiniz test ortamınızda çalışmaz (artı bir entegrasyon testine dönüşmüştür).

Çözüm? Veri Erişim Hizmetiniz için bir Arayüz kullanın ve sınıfınızı bir ünite olarak test edebilmeniz için bu arayüzü Taklit Edin .

Öte yandan, WPF ve Silverlight, ciltleme söz konusu olduğunda hiçbir zaman Arayüzlerle oynamıyor. Bu oldukça iğrenç bir kırışıklık.


2
duy duymak! Polimorfizm gibi diğer problemleri çözmek için arayüzler icat edildi. Ancak, benim için, bir Bağımlılık Enjeksiyonu paterni uygularken kendi başlarına geliyorlar.
andy

29

Arayüzler (statik) polimorfizmin bel kemiğidir! Arayüz önemli olan şey. Kalıtım, alt sınıflar temel olarak ebeveynin zaten uygulanmış arayüzünü devraldığı için arayüzler olmadan çalışmaz.

Onlardan ne sıklıkta faydalanıyorsunuz ve ne yapıyorsunuz?

Oldukça sık. Takılabilir olması gereken her şey benim uygulamalarımda bir arayüz. Çoğu zaman, aynı davranışı sağlaması gereken ilgisiz sınıflarınız vardır. Bu tür sorunları mirasla çözemezsiniz.

Aynı veriler üzerinde işlem yapmak için farklı algoritmalara mı ihtiyacınız var? Bir arayüz kullanın ( bkz. Strateji deseni )!

Farklı liste uygulamaları kullanmak ister misiniz? Bir arabirime karşı kodlama yapan ve arayan kişinin uygulama konusunda endişelenmesine gerek yok!

Tek bir nedenden ötürü, yaş ara yüzlerine karşı kodlama yapmak iyi bir uygulama (sadece OOP'de değil) olarak kabul edildi: İhtiyaçlarınızı karşılamadığını fark ettiğinizde bir uygulamayı değiştirmek kolaydır. Bunu sadece birden fazla kalıtım ile elde etmeye çalışırsanız ya da gerekli arayüzü sağlamak için boş sınıflar oluşturarak kaynatırsanız çok hantal olur.


1
Polimorfiyi hiç duymadım, polimorfizmi mi kastediyorsunuz?
Steven Jeuris 14:11

1
söylenirse, eğer microsoft ilk olarak çoklu mirasa izin verirse, arayüzlerin varlığının bir nedeni olmazdı
Pankaj Upadhyay

10
@Pankaj Upadhyay: Çoklu kalıtım ve arayüzler iki farklı ayakkabı çiftidir. Farklı davranışları olan iki alakasız sınıfın arayüzüne ihtiyacınız varsa? Bunu çoklu miras yoluyla çözemezsiniz. Zaten ayrı ayrı uygulamak zorundasınız. Ve sonra polimorfik davranış sağlamak için arayüzü tanımlayacak bir şeye ihtiyacınız olacak. Çoklu kalıtım, birçok durumda aşağıya inmek için kör bir sokaktır ve kendinizi er ya da geç ayağından vurmak çok kolaydır.
Şahin

1
Basitleştirelim. Arabirim iki işlevi uygularsa, Ekran ve Yorum ve bunları uygulayan bir sınıf var. Öyleyse neden arayüzü kaldırmıyorum ve işlevleri doğrudan kullanmıyorum. Demek istediğim, sadece size uygulanması gereken işlevlerin adlarını sağladıkları. Eğer biri bu fonksiyonları hatırlayabiliyorsa, neden bir arayüz oluşturuyorsun?
Pankaj Upadhyay

9
@Pankaj, arabirim için ihtiyacınız olan şey buysa, kullanmayın. Sınıfın her yönünü görmezden gelmek ve temel türüne, yani arayüze erişmek isteyen bir programınız olduğunda bir arayüz kullanırsınız. Alt sınıfların hiçbirini bilmelerine gerek yok, sadece arabirimin türünden olduğunu. Böylece, alt sınıfın uygulanmış yöntemini nesnenin arayüzüne referans yoluyla çağırabilirsiniz. Bu temel miras ve tasarım malzemesidir. Onsuz, C'yi de kullanabilirsiniz. Açıkça kullanmasanız bile, çerçeve onsuz çalışmayacaktır.
Jonathan Henson

12

Muhtemelen kullandınız foreachve oldukça kullanışlı bir yineleme aracı olarak buldunuz. IEnumerable işlevi için bir arayüz gerektirdiğini biliyor muydunuz ?

Bu kesinlikle bir arayüzün kullanışlılığına değinen somut bir durum.


5
Aslında, foreach IEnumerable gerektirmez: msdn.microsoft.com/en-us/library/9yb8xew9%28VS.80%29.aspx
Matt H

1
Bunları çalıştım ama kulağı diğer eliyle tutmak gibi bir şey. Birden fazla kalıtıma izin verildiyse, ara yüz uzak bir seçim olabilirdi.
Pankaj Upadhyay

2
Arabirimler, çoğu zaman unutulan bir şey olup, çoklu kalıtımdır. Ancak, davranış ve durumun birden fazla mirasına izin vermezler. Karışımlar veya özellikler, davranışların çoklu kalıtımına izin verir, ancak sorunlara neden olan paylaşılan bir duruma izin vermez: en.wikipedia.org/wiki/Mixin
Matt H

@Pankaj, offtopic, ama anadilin ne olduğunu sormamın sakıncası var mı? "Kulağı diğer eliyle tutmak" harika bir deyim ve nereden geldiğini merak ediyordum.
Kevin

3
@Iceman. LOL .... Ben Hindistanlıyım. Ve işte bu, kolay işleri zor yoldan yapmayı yansıtan ortak bir deyimdir.
Pankaj Upadhyay 14:11

11

Arabirimler bir fiş gibi nesneleri kodlamak için ev kablolamasıdır. Radyonuzu doğrudan ev kablolarınıza lehimlemek ister misiniz? Elektrikli süpürgen nasıl? Tabii ki değil. Fiş ve içine oturduğu priz, ev kablolarınızla bu enerjiden ihtiyacı olan cihaz arasında “arayüz” oluşturur. Evinizin kablolamasının cihazda üç uçlu topraklı fiş kullanmasından başka bir şey bilmemesi ve 120VAC <= 15A'da elektrik gücü gerektirmesi gerekir. Buna karşılık, cihaz, 120VAC <= 15A sağlayan uygun şekilde yerleştirilmiş bir veya daha fazla üç uçlu prize sahip olması dışında, evinizin nasıl kablolandığı hakkında gizli bilgi gerektirmez.

Arabirimler kodda çok benzer bir işlevi yerine getirir. Bir nesne, belirli bir değişkenin, parametrenin veya dönüş tipinin bir arayüz tipinde olduğunu beyan edebilir. Arayüz doğrudan bir newanahtar kelimeyle başlatılamaz , ancak nesnem üzerinde çalışması gereken arayüzün uygulaması verilebilir veya bulunabilir. Nesne bağımlılığına sahip olduğunda, bağımlılığın ne olduğunu tam olarak bilmek zorunda değildir, bağımlılığa ilişkin X, Y ve Z yöntemlerini çağırabileceğini bilmesi gerekir. Arabirimin uygulamaları nasıl kullanılacağını bilmek zorunda değildir, sadece X, Y ve Z yöntemlerini belirli imzalarla sağlamaları beklenir.

Böylece, aynı arabirimin arkasındaki birden çok nesneyi soyutlayarak, bu arabirimin nesnelerinin herhangi bir tüketicisine ortak bir işlevsellik seti sağlarsınız. Nesnenin, örneğin bir Liste, Sözlük, LinkedList, OrderedList veya başka bir şey olduğunu bilmek zorunda değilsiniz. Bunların hepsinin IEnumerable olduğunu bildiğiniz için, bu koleksiyonlardaki her bir öğeye birer birer geçmek için IEnumerable yöntemlerini kullanabilirsiniz. Bir çıktı sınıfının bir Konsol Yazarı, bir Dosya Yazıcısı, Bir Ağ Yayını Yazıcısı ve hatta diğer yazar türlerini alan Çok Noktaya Yayın Yazıcısı olduğunu bilmek zorunda değilsiniz; bilmeniz gereken tek şey, hepsinin IWriters (ya da her neyse) olduğu ve bu nedenle bir dizgenin içine geçirebileceğiniz bir "Yazma" yöntemine sahip olmaları ve bu dizgenin çıktısı oluşması.


7

Programcının (ilk başta, en azından) çoklu miras almasının açıkça bir muamele olmasına rağmen, bu neredeyse önemsiz bir ihmaldir ve (çoğu durumda) çoklu mirasa güvenmemeniz gerekir. Bunun nedenleri karmaşıktır, ancak gerçekten öğrenmek istiyorsanız, onu destekleyen en ünlü iki ( TIOBE endeksi ) programlama dilinden elde edilen deneyimi düşünün : C ++ ve Python ( sırasıyla 3. ve 8.).

Python'da çoklu kalıtım desteklenir, ancak programcılar tarafından evrensel olarak yanlış anlaşıldığını ve nasıl çalıştığını bildiğinizi belirtmek, konuyla ilgili bu makaleyi okumak ve anlamak anlamına gelir: Yöntem Çözüm Emri . Python'da gerçekleşen başka bir şey de, dillerin içine girilen arayüzlerin - Zope.Interfaces.

C ++ için, "elmas hiyerarşisi C ++" google'da sizi korumak üzere olan çirkinliği görün. C ++ profesyonelleri çoklu kalıtımın nasıl kullanılacağını bilir. Diğer herkes genellikle sonuçların ne olacağını bilmeden uğraşır. Arayüzlerin ne kadar yararlı olduğunu gösteren başka bir şey, birçok durumda bir sınıfın ebeveyninin davranışını tamamen geçersiz kılması gerekebileceği gerçeğidir. Bu gibi durumlarda, ebeveyn uygulaması gereksizdir ve alt sınıfı yalnızca C # yaşında önemli olmayabilir, ancak gömülü programlama yaptığınızda önemli olan ebeveynin özel değişkenleri için olan bellekle yükler. Bir arabirim kullanırsanız, bu sorun yoktur.

Sonuç olarak, ara yüzler bence OOP'nin vazgeçilmez bir parçası çünkü sözleşmeyi yürürlüğe koyuyorlar. Çoklu kalıtım, sınırlı durumlarda ve genellikle onu nasıl kullanacağını bilenlere faydalıdır. Dolayısıyla, eğer bir acemiyseniz, çoklu kalıtım eksikliği ile tedavi edilen sizsiniz - bu size hata yapmamak için daha iyi bir şans verir .

Ayrıca, tarihsel olarak, bir arabirim fikri Microsoft'un C # tasarım özelliklerinden çok daha önce kaynaklanmaktadır. Çoğu kişi, C # 'yı Java üzerinden yükseltme (çoğu anlamda) olarak düşünür ve C #' un arayüzlerini nereden aldığını tahmin eder - Java. Protokol aynı kavram için daha eski bir kelimedir ve .NET'ten çok daha eskidir.

Güncelleme: Şimdi farklı bir soruya cevap vermiş olabileceğimi görüyorum - neden çoklu kalıtım yerine arayüzler oluşturuyorsun, ama bu aradığınız cevap gibi görünüyordu. Ayrıca bir OO dili ikisinden en az birine sahip olmalı ve diğer cevaplar asıl sorunuzu kapsamalıdır.


6

Arayüz kullanmadan temiz, nesne yönelimli C # kodunu hayal etmem zor. Sınıfları belirli bir temel sınıftan miras almaya zorlamadan belirli işlevlerin kullanılabilirliğini zorlamak istediğinizde bunları kullanırsınız ve bu, kodunuzun ilgili (düşük) birleştirme düzeyine sahip olmasını sağlar.

Çok sayıda mirasın, kendi başına çektiği acılarla geldiğini iddia etmeden önce bile, çoklu mirasın arayüzlere sahip olmaktan daha iyi olduğuna katılıyorum. Arayüzler, polimorfizmi ve kodun yeniden kullanılmasını sağlamak için temel bir araçtır, daha fazlasına ne gerek var?


5

Ben şahsen soyut sınıfı seviyorum ve onu bir arayüzden daha fazla kullanıyorum. Temel fark, IDisposable, IEnumerable ve benzeri gibi .NET arabirimleriyle ve COM birlikte çalışabilirliği ile bütünleşmesidir. Ayrıca, arayüz soyut bir sınıftan daha az çaba harcamaktadır ve bir sınıf birden fazla arayüzü uygularken, sadece bir sınıftan miras alabilir.

Bununla birlikte, bir arayüz kullanacağım çoğu şeyin soyut bir sınıf tarafından daha iyi sunulduğunu söyledim. Saf sanal işlevler - soyut işlevler - bir uygulamacıyı, bir arabirimin tüm üyelerini tanımlamak için bir uygulayıcıya zorlama biçimine benzer bir işlevi tanımlamak için zorlamanızı sağlar.

Ancak, genellikle süper sınıfa belirli bir tasarım uygulamak istemediğiniz zaman bir arabirim kullanırsınız; ancak, çoğunlukla uygulanmış olan yeniden kullanılabilir bir tasarıma sahip olmak için soyut bir sınıfı kullanırsınız.

System.ComponentModel ad alanını kullanarak eklenti ortamları yazarken arayüzleri yoğun olarak kullandım. Oldukça kullanışlı geliyorlar.


1
Çok iyi koymak! Sanırım soyut derslerle ilgili makalemi beğeneceksin. Soyutlama her şeydir .
Steven Jeuris 14:11

5

Bununla ilgili olduğumu söyleyebilirim. OO ve C # hakkında ilk öğrenmeye başladığımda Arayüzleri de alamadım. Bu iyi. Arayüzlerin uygunluğunu takdir etmenizi sağlayacak bir şeye rastlamamız yeterli.

İki yaklaşımı deneyeyim. Ve genellemeler için beni bağışlayın.

Deneyin 1

Anadili İngilizce olduğunuzu söyleyin. İngilizcenin anadili olmadığı başka bir ülkeye gidersiniz. Yardıma ihtiyacın var. Sana yardım edebilecek birine ihtiyacın var.

"Amerika Birleşik Devletleri'nde mi doğdun?" Bu mirastır.

Yoksa, "Hey, İngilizce konuşabiliyor musun" diye mi soruyorsun? Bu arayüz.

Ne yaptığını önemsiyorsan, arayüzlere güvenebilirsin. Ne olduğunu önemsiyorsan, mirasa güveniyorsun.

Mirasa güvenmek tamam. İngilizce bilen, çaydan ve futboldan hoşlanan birine ihtiyacınız varsa, bir İngiliz istemek daha iyi. :)

2 dene

Tamam, başka bir örnek deneyelim.

Farklı veritabanları kullanıyorsunuz ve onlarla çalışmak için soyut sınıflar uygulamanız gerekiyor. Sınıfınızı DB satıcısından bir sınıfa geçireceksiniz.

public abstract class SuperDatabaseHelper
{
   void Connect (string User, string Password)
}

public abstract class HiperDatabaseHelper
{
   void Connect (string Password, string User)
}

Çoklu miras mı diyorsun? Bunu yukarıdaki dava ile deneyin. Yapamazsın Derleyici, hangi Connect yöntemini aramaya çalıştığınızı bilemez.

interface ISuperDatabaseHelper
{
  void Connect (string User, string Password)
}

interface IHiperDatabaseHelper
{
   void Connect (string Password, string User)
}

Şimdi, en azından C # 'da çalışabileceğimiz bir şey var - arayüzleri açıkça uygulayabiliyoruz.

public class MyDatabaseHelper : ISuperDatabaseHelper, IHiperDatabaseHelper
{
   IHiperDataBaseHelper.Connect(string Password, string User)
   {
      //
   }

   ISuperDataBaseHelper.Connect(string User, string Password)
   {
      //
   }

}

Sonuç

Örnekler en iyisi değil, fakat bunun karşısında bir noktaya değiniyor.

İhtiyaç duyduğunuzda sadece arayüzleri “alırsınız”. Onlara kadar senin için olmadığını düşüneceksin.


İlk deneme oyumu veren şeydi.
osundblad

1
Bundan böyle Amerikan ve İngiliz Konuşmacı analojisini tamamen kullanıyorum. Bu mükemmel.
Bryan Boettcher

Daha basit bir şekilde açıkladı! Fantastik.
Aimal Khan

4

2 ana sebep var:

  1. Çoklu kalıtım eksikliği. Bir temel sınıftan miras alabilir ve istediğiniz sayıda arabirim uygulayabilirsiniz. .NET'te çoklu devralma işlemini "yapmanın" tek yolu budur.
  2. COM birlikte çalışabilirliği. "Eski" teknolojiler tarafından kullanılması gereken herhangi bir şeyin tanımlanmış arayüzlere sahip olması gerekir.

Nokta 1 kesinlikle microsoft geliştiricileri kendileri tarafından geliştirilen nedeni ve nedeni
Pankaj Upadhyay

1
@ Panja Aslında, arayüz fikrini Java'dan aldılar (C # özelliklerinin iyi bir parçası gibi).
Oliver Weiler

3

Arayüz kullanımı, sistemin ayrık kalmasına yardımcı olur ve böylece yeniden döşenmesi, değiştirilmesi ve yeniden konuşlandırılması daha kolaydır. Nesne yönelimli ortodoksiye çok temel bir kavramdır ve ilk önce C ++ gurusu arayüzlere oldukça eşdeğer olan "saf soyut sınıflar" yaptığında öğrendim.


Ayrıştırma önemlidir, çünkü sistemin farklı bileşenlerini birbirinden bağımsız tutar. Bir bileşendeki büyük darbeli değişikliklerin bile diğer bileşenlere dalgalanmaması. Elektrik fişlerini elektrik dağıtım şirketinize bir arayüz olarak düşünün (voltajı ve fişin fiziksel pimlerini ve biçimini belirtin). Bu arabirim sayesinde, yardımcı program güç üretme şeklini tamamen değiştirebilir (örn. Güneş enerjisi teknolojisini kullanır), ancak hiçbir cihaz değişmeden bile fark edemez.
miraculixx

3

Arayüzler kendi başlarına çok kullanışlı değildir. Ancak, somut sınıflar tarafından uygulandığında, bir veya daha fazla uygulamaya sahip olma esnekliğini sağladığını görüyorsunuz. Bonus, arayüzü kullanan nesnenin fiili uygulamanın detaylarının - kapsülleme - denilen ayrıntıların nasıl gittiğini bilmesine gerek olmamasıdır.


2

Çoğunlukla kod yeniden kullanılabilirliği için kullanılır. Arabirime kodlarsanız, bu arabirimden devralan ve her şeyi bozmayan farklı bir sınıf kullanabilirsiniz.

Ayrıca, müşterilere bir sınıfın ne yaptığını (böylece tüketebilecekleri) bildirmek istediğiniz, ancak onlara gerçek kodu vermek istemediğiniz web hizmetlerinde çok kullanışlıdır.


2

Genç bir programcı / geliştirici olarak, sadece C # öğrenme, arayüzün kullanışlılığını göremeyebilirsiniz, çünkü sınıflarınızı kullanarak kodlarınızı yazabilirsiniz ve kod iyi çalışır, ancak gerçek yaşam senaryosunda ölçeklenebilir, sağlam ve bakım yapılabilir bir uygulama oluşturmak gerekir. sadece arabirim kullanılarak mümkün olabilen bazı mimari ve desenler, örneğin bağımlılık enjeksiyonunda.


1

Gerçek bir dünya uygulaması:

Arabirim türü olarak bir nesneyi yayınlayabilirsiniz:

IHelper h = (IHelper)o;
h.HelperMethod();

Bir arayüz listesi oluşturabilirsiniz

List<IHelper> HelperList = new List<IHelper>();

Bu nesnelerle, arayüz yöntemlerinden veya özelliklerinden herhangi birine erişebilirsiniz. Bu şekilde, bir programın parçası için bir arayüz tanımlayabilirsiniz. Ve etrafındaki mantığı oluştur. Daha sonra başka biri arayüzünüzü kendi İş nesnelerine uygulayabilir. BO'nun değişmesi durumunda, arayüz bileşenleri için mantığı değiştirebilir ve parçanız için mantığın değiştirilmesini gerektirmezler.


0

Arabirimler, sisteminizin sunduğu belirli türdeki mesajları anlama (ve bunlara abone olma) için bir mekanizma sunarak eklenti tarzı modülerliği ödünç verir. Ben detaylandırırım.

Başvurunuzda, bir form yüklendiğinde veya her yeniden yüklendiğinde, barındırdığı her şeyin silinmesini istediğinize karar verirsiniz. Uygulayan bir ICleararayüz tanımlarsınız Clear. Ek olarak, kullanıcı kaydet düğmesine her bastığında, formun durumunu devam ettirmeye çalışması gerektiğine karar verirsiniz. Böylece, uyduğu her şey ISavedurumunu devam ettirmek için bir mesaj alır. Elbette, pratik olarak konuşursak, çoğu arayüz birkaç mesajla ilgilenir.

Arayüzleri birbirinden ayıran şey, ortak davranışın kalıtım olmadan gerçekleştirilebilmesidir. Belirli bir arayüzü uygulayan sınıf, bir komut verildiğinde nasıl davranacağını (bir komut mesajı) veya sorgulandığında nasıl cevap vereceğini (bir sorgu mesajı) anlar. Temel olarak, uygulamanızdaki sınıflar, uygulamanızın sağladığı mesajları anlar. Bu, işlerin takılabileceği modüler bir sistem kurmayı kolaylaştırır.

Çoğu dilde , bir arayüze bağlı olan şeyleri sorgulamak için mekanizmalar ( LINQ gibi ) vardır. Bu, genellikle koşullu mantığı ortadan kaldırmanıza yardımcı olacaktır, çünkü benzer şeylere (aynı miras zincirinden türetilmesi gerekmeyen), aynı şekilde nasıl davranacağını (belirli bir mesaja göre) anlatmanız gerekmeyecektir. Bunun yerine, belirli bir mesajı anlayan her şeyi toplarsınız (bir arayüze bağlı kalır) ve mesajı yayınlarsınız.

Örneğin, değiştirebilirsiniz ...

Me.PublishDate.Clear()
Me.Subject.Clear()
Me.Body.Clear()

...ile:

For Each ctl As IClear In Me.Controls.OfType(Of IClear)()
    ctl.Clear()
Next

Hangi etkili bir şekilde çok sesler:

Sesini duy, Sesini duy! Temizlemeyi anlayan herkes, lütfen Clearşimdi!

Bu şekilde, programatik olarak her bireye kendisini temizlemek için her şeyi söylemekten kaçınabiliriz. Ve silinebilir öğeler gelecekte eklendiğinde, herhangi bir ek kod olmadan yanıt verir.


0

Aşağıdaki sahte kod:

class MyClass{

    private MyInterface = new MyInterfaceImplementationB();

    // Code using Thingy 

}

interface MyInterface{

    myMethod();

}

class MyInterfaceImplementationA{ myMethod(){ // method implementation A } }

class MyInterfaceImplementationB{ myMethod(){ // method implementation B } }

class MyInterfaceImplementationC{ myMethod(){ // method implementation C } }

Son sınıflar tamamen farklı uygulamalar olabilir.

Çoklu miras mümkün olmadıkça, miras, ebeveyn sınıfının uygulanmasını empoze eder ve işleri daha katı hale getirir. Diğer taraftan arayüzlere karşı programlama, kodunuzun veya bir çerçevenin son derece esnek olmasına izin verebilir. Eğer dilediğiniz bir davaya rastlarsanız, bir miras zincirinde sınıflar arasında değiş tokuş yapabilirsiniz, bunun nedenini anlarsınız.

Örneğin, başlangıçta diskten veri okuma amaçlı bir Reader sağlayan bir çerçeve, aynı nitelikteki bir şeyi ancak tamamen farklı bir şekilde yapmak için tekrar uygulanabilir. Örneğin Mors kodu yorumlamak gibi.

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.