Arabirimler ve yalnızca soyut yöntemlere sahip soyut sınıflar arasında bir fark var mıdır?


9

Diyelim ki soyut bir sınıfımız var ve bu sınıfta sadece soyut yöntemler var. Bu soyut sınıf, yalnızca aynı yöntemlere sahip bir arabirimden farklı mıdır?

Bilmek istediğim şey, hem soyut hem de eşdeğer bir Arayüz ile Soyut Sınıf arasında hem felsefi, objektif hem de temel programlama dili uygulamasında herhangi bir fark olup olmadığıdır.


Hangi dil?
kevin cline

Anlayabildiğim kadarıyla, sorunuz iki kez tekrarlanır : burada ve burada . Ve bu iki cevap dil ​​agnostik, orada C # için özel bir şey
gnat

3
@blank Sorunuza uygulanan Yinelenen durumla aynı fikirde değilim, bu yüzden yeniden açtım. Ayrıca, sorduğunuza inandığımı daha da netleştirmek için sorunuzu düzenledim.
maple_shaft

Yanıtlar:


22

Teknik olarak, farklılıklar gerçekten önemli değildir, ancak kavramsal olarak, tamamen farklı şeylerdir ve bu da başkalarının bahsettiği teknik farklılıklara yol açar.

Soyut bir süper sınıf tam olarak göründüğü gibidir, Kediler ve Köpekler Hayvanlar gibi diğer birçok tür tarafından paylaşılan yaygın bir türdür.

Bir arayüz aynı zamanda kulağa nasıl geliyorsa, diğer sınıfların nesne ile iletişim kurabildiği bir arayüzdür. Cat Walk yapmak istiyorsanız, sorun değil, çünkü Cat bir CanWalk arabirimi uygular. Kertenkele için de aynı şey olsa da çok farklı yürüyorlar. Öte yandan, bir Yılan CanWalk'ı uygulamıyor, bu yüzden ona Yürütmesini söyleyemezsin. Bu arada, Lizard ve Snake (veya muhtemelen daha açık alt sınıflar - ben uzman değilim) hem derilerini dökebilir hem de CanShed'i uygulayabilirken, bir Cat bunu yapamazdı.

Ama hepsi hala Hayvan ve canlı ya da ölü gibi bazı ortak özelliklere sahipler.

Bu nedenle bir arabirimdeki tüm yöntemlerin genel (veya açıkça C # olarak) uygulanması gerekir. Neden bir arabirimde nesneyle arabirim oluşturan sınıftan gizlenen nokta nedir? Ayrıca, bir dil birden fazla kalıtımı desteklemese bile, bir nesneye birden çok arabirime sahip olmanızın nedeni de budur.

Sorunuza geri dönmek için, bu şekilde baktığınızda, tamamen soyut bir üst sınıfa sahip olmanın nadiren bir nedeni vardır.


4
+1, ancak kediler yılanlardan veya kertenkelelerden çok daha sinir bozucu bir şekilde dökülür.
Matthew Flynn

Teknik olarak: Soyut yöntemler korunabilir. Arayüz yöntemleri cant.
Jacques Koorts

19

Çoğu OOP dilinde, bir uygulayıcı sınıf yalnızca bir soyut sınıftan türetilebilir, ancak birden çok arabirim uygulayabilir.


3
çoğu? hangilerini sayıyorsun Tanıdığım çoğu OOP dili arayüz veya soyut sınıf içermiyor. C ++ yalnızca soyut sınıflara sahiptir.
kevin cline

10
@kevincline: muhtemelen C #, Java ve VB.NET.
tdammers

1
@kevincline, bence sadece bir "ikisine de sahip" yok. IIRC, Ada'da arayüzün motivasyonunun, tasarımcıların genel bir çoklu miras özelliği istemediklerini, ancak özel arayüz durumunun sağlanamayacak kadar önemli olduğu düşünülüyordu.
AProgrammer

@tdammers: LOL. O oldu , sağ bir şaka?
kevin cline

3

Çoklu kalıtıma izin veren ve arayüzleri olmayan C ++ gibi bir dilde, tüm yöntemlerin soyut olduğu soyut sınıflar arayüzler olarak kullanılabilir. C ++ ile o kadar çok çalışmadım, ancak temel sınıflarda aynı ada sahip yöntemler olduğunda çoklu miras sorunlara neden olabilir sanırım.

PHP ve C # gibi dillerde, arayüzler benzer bir polimorfizme ulaşmanın bir yolunu sağlar, ancak soyut bir sınıfı devralmak ve bir arabirim uygulamak arasında kavramsal bir fark olduğu için buna "kalıtım" demekten hoşlanmam. Arabirimler çatışma sorununu ortadan kaldırır, çünkü kendileri uygulama sağlamazlar.

Bir arabirim dış dünya için bir sözleşme görevi görürken, soyut bir sınıf bir uygulama sağlayabilir, ancak bir arabirimi "taklit etmek" için kullanılırsa, büyük olasılıkla olmayacaktır.

Temel kavramsal fark, bir sınıf başka bir sınıfı miras aldığında (soyut ya da değil), "bir" ilişkisi vardır, yani a Carbir Vehicleve Dogbir 'dir Animal. Bir arayüzle, nesnenin önemli yaptığı şey budur. Her iki yüzden Carve Dogcan Move()ve uygulayabilir çünkü tüketici bunu biliyor Movable, ama bir araba kesinlikle değil Dogveya bir Animal. Ve hareket uygulaması farklı olacak (tekerlekler bacaklara karşı), ancak tüketim kodu umursamıyor ve olmamalıdır. Arayüzler uygulamadan ziyade tüketen kodla ilgilidir.

Ana nokta, seçtiğiniz dilde arayüzleriniz varsa, bunları orada oldukları şeyler için kullanın. Değilse (C ++ gibi), onları saf soyut sınıfları kullanarak taklit edebilirsiniz.


Bir IAnimal sahip olan hem böylece Arayüz yanı türüdür Dogve Cat vardır .
Amy Blankenship

Yapabilirsiniz, ama bence, arayüzler dış dünyaya maruz kalan davranışlarla ilgilidir ve nesnelerin ne olduğu hakkında o kadar da değil. Kalıtım, bir şeyin başka bir şey olduğunu ima eder (Kedi bir Hayvandır). Bir arayüz sadece bu nesnenin neler yapabileceğini söyler. Bu yüzden bir şey "bir şey miras" yerine bir "uygular" demek istiyorum, ki ben en çok çalıştığım .Net insanlar (ben sözdizimi kalıtım ve uygulama için aynı olduğu için) söyleyebilirim.
Ivan Pintar

2

Soyut sınıflar soyut korumalı yöntemler (birlikte çalıştığım dillerde) içerebilir, arayüzlerde yöntemler genellikle her zaman herkese açıktır. Bu farkın bilmediğim faydalı sömürülere izin verip vermediği.

Düzenle İlk olarak özel bir soyut yöntemin hiçbir faydası olmadığını düşündüm, ancak şimdi bu yöntemin asla çağrılmamasını sağlamak için kullanılabileceğini hatırladım. Bu şekilde, bir nesnenin kopya oluşturucusunun çağrılmasını önleyebilirsiniz.


1
Korumalı sanal (geçersiz kılmaya uygun) yöntemler, bir çerçevenin parçası olan sınıflar veya bunun gibi bir şey için yararlı olabilir. Bu şekilde, özeti devralan bir sınıftaki özel kodun bu işlevselliği sağlamasını sağlarlar. Bu, temel sınıftaki bir arayüzü devralarak da gerçekleştirilebilir, ancak aslında yöntemlerini uygulayarak değil
Ivan Pintar

Evet, böyle bir şey düşünüyordum, ama onunla hiç tecrübem yok, bu yüzden yargılayamadım. Giriş için teşekkürler.
Thomas

Sadece bir not. Bazı dillerde, türetilmiş sınıflarda özel sanal yöntemler geçersiz kılınabilir.
Johan Boulé

2

Evet, farklılar. Aksi takdirde dil tasarımcıları her ikisini de sağlamazdı. Sınıfları ve arayüzleri ayıran iki dil biliyorum: Java ve C #, Java'nın mutant klonu. Tasarımcılar, çoklu sınıf mirasını desteklemekten kaçınmak için arayüzler oluşturdular. Diğer birçok dil, birden çok sınıf mirasını destekler ve sonuç olarak sınıfları ve arabirimleri ayırmaz.


2

Bence temel fark şudur: Soyut bir sınıfta - tüm yöntemlerin hepsi soyut olsa bile, yine de (özel yöntemler veya kurucular şeklinde) uygulayan sınıflara veri üyeleri (örnek değişkenler) ve bazı kodlar sağlayabilir, statik bloklar; alt sınıflar için yapılan çalışmaların bir kısmını yapmak ve uygulamada onlara yardımcı olmak.

Bir olumlu yan etki: kod tek bir yerde, düzeltmeler yapmak için tek bir yerde. alt sınıflar sadece süper sınıf yöntemini çağırabilir ve sonra süper sınıf eylemleri durumları için yeterliyse başka bir şey veya hiçbir şey yapamazlar. Süper sınıf, her alt sınıfın bu kararı vermesini ister, bu yüzden tüm uygulamasını soyut olarak işaretlemiştir (bazıları da boş olabilir)

Soru ile ilgili değildir: ancak arayüzlere sahip olmak, bir sınıfın iki farklı sözleşme uygulayabileceği anlamına gelir. Bu soyut bir süper sınıfa göre bir arayüzün avantajı


1
Herhangi bir uygulama olmadan soyut yöntemler tanımlanmıyor ve uygulamayı miras sınıflarına bırakıyor mu?
Ivan Pintar

evet sağ o zaman ben sadece saymak onun sadece değişkenler, yapıcılar ve statik ve özel yöntemler bunları saymak
tgkprog 19:13

@Pinetree, pratikte çoğu zaman Özet Sınıflarınızda en azından küçük bir "gerçek" kod isteyeceksiniz (en azından kullandığım dilde, Soyut Sınıflar için özel bir yapıya sahip olmayan).
Amy Blankenship

@AmyBlankenship evet, çoğu zaman soyut sınıfların "gerçek" kodu vardır (bunun için oradalar). Ancak, arayüzleri olmayan C ++ gibi bir dilde arayüz görevi gören tamamen soyut bir sınıf bağlamında soyut yöntemlerden bahsediyordum.
Ivan Pintar
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.