Arayüz ve Soyut Sınıf (genel OO)


1413

Son zamanlarda bir Interface ve Abstract sınıfı arasındaki farkların sorulduğu iki telefon görüşmem oldu. Düşünebileceğim her yönünü açıkladım, ancak belirli bir şeyden bahsetmemi bekliyorlar ve ne olduğunu bilmiyorum.

Deneyimlerime göre, aşağıdakilerin doğru olduğunu düşünüyorum. Eğer önemli bir noktayı kaçırırsam lütfen bana bildirin.

Arayüz:

Bir Arabirimde bildirilen her bir Yöntemin alt sınıfta uygulanması gerekir. Bir Arabirim'de yalnızca Olaylar, Temsilciler, Özellikler (C #) ve Yöntemler bulunabilir. Bir sınıf birden fazla Arayüz uygulayabilir.

Soyut Sınıf:

Alt sınıf tarafından yalnızca Soyut yöntemler uygulanmalıdır. Bir Abstract sınıfının uygulamalarla normal yöntemleri olabilir. Abstract sınıfı ayrıca Olaylar, Delegeler, Özellikler ve Yöntemlerin yanında sınıf değişkenlerine de sahip olabilir. Bir sınıf yalnızca bir soyut sınıfı yalnızca C # 'da Çoklu kalıtım olmaması nedeniyle uygulayabilir.

  1. Tüm bunlardan sonra, görüşmeci "Ya sadece soyut yöntemlerle bir Özet dersiniz olsaydı? Arayüzden farkı ne olurdu?" Cevabı bilmiyordum ama sanırım yukarıda da bahsettiğim miras doğru mu?

  2. Başka bir görüşmeci bana arayüzde bir Genel değişkeniniz olsaydı, bu Soyut Sınıfdakinden farklı olurdu? Arayüz içinde genel bir değişkene sahip olamayacağınız konusunda ısrar ettim. Ne duymak istediğini bilmiyordum ama memnun değildi.

Ayrıca Bakınız :


412
İkisi arasındaki farkı bilmek önemli olsa da, bu iyi bir röportaj sorusu değil, imo. Eğer iş OO konuları üzerine bir kitap yazmadığı sürece. Bu yarasalar için çalýţmasan iyi olur.
Alan

107
@Alan: Aslında bunu bir röportaj sorusu olarak sevdim, ama birisini bu şekilde taramam - muhtemelen daha çok "Hiyerarşi tanımlarken, soyut bir temel sınıf üzerinde bir arayüz nerede seçerdiniz?" ", Veya benzeri.
Reed Copsey

11
Belki daha tasarım odaklı bir cevap peşindeydiler ... senin gibi ben de teknik bir soru olarak ele alırdım.
CurtainDog

16
Burada güzel tablo farklılıkları: mindprod.com/jgloss/interfacevsabstract.html
Rajat_R

30
@Kave: I insisted you can't have a public variable inside an interface.Bence arayüzün genel değişkeni olabilir. Aslında, arabirimdeki değişkenler otomatik olarak genel ve son şeklindedir.
Bir Öğrenci

Yanıtlar:


746

Sorunuz "genel OO" için olduğunu belirtmekle birlikte, bu terimlerin .NET kullanımına odaklanıyor gibi görünüyor.

.NET'te (Java için benzer):

  • arayüzlerin durumu veya uygulaması olamaz
  • bir arabirimi uygulayan bir sınıf, o arabirimin tüm yöntemlerinin uygulanmasını sağlamalıdır
  • soyut sınıflar devlet (veri üyeleri) ve / veya uygulama (yöntemler) içerebilir
  • soyut sınıflar, soyut yöntemleri uygulamadan miras alınabilir (böyle bir türetilmiş sınıf soyutun kendisidir)
  • arayüzler çoklu kalıtsal olabilir, soyut sınıflar olmayabilir (bu muhtemelen arayüzlerin ayrı sınıflardan ayrı olarak varlığının temel somut nedenidir - genel MI sorunlarının çoğunu ortadan kaldıran çoklu kalıtım uygulamasına izin verir).

Genel OO terimleri olarak, farklılıklar mutlaka iyi tanımlanmış değildir. Örneğin, benzer katı tanımlara sahip olabilen C ++ programcıları vardır (arabirimler, uygulama içeremeyen soyut sınıfların katı bir alt kümesidir), bazıları ise bazı varsayılan uygulamalara sahip soyut bir sınıfın hala bir arabirim olduğunu veya soyut olmayan bir sınıf olduğunu söyleyebilir. class yine de bir arabirim tanımlayabilir.

Aslında, genel yöntemlerin özel sanal yöntemlere 'thunk' sanal olmayan yöntemler olduğu Sanal Olmayan Arayüz (NVI) adı verilen bir C ++ deyimi vardır:


7
Teşekkür ederim. Bence cevabınız belirtildiği için + tüm dinlenmelere iyi bir genel bakış, yanıtınızı nihai bir cevap olarak işaretliyorum. Haklısın, genel OO'yu sordum, çünkü ilk görüşmeci genel OO'yu istedi, ama ben bir C # adamı olduğum için bunu unutmaya eğilimliyim. ;-) Ayrıca C ++ açıklaması için teşekkürler, her zaman olduğu gibi c ++ zihin üfleme.
Houman

6
Bence Michael'ın yaptığı açıklamada önemli bir nokta, bir arabirim uygularken arabirimdeki tüm üyeleri uygulamalısınız GEREKİR, ancak soyut bir sınıftan miras alırken, ebeveynlerinin üyelerini uygulamak için bir çocuk sınıfı tarafından GEREKLİ DEĞİLDİR
Guillermo Gomez

82
+1: Röportajı düzenleyen maymunların, diğer dillerin OO'yu farklı şekilde uyguladığını bile fark etmediğine bahse girmeye istekli olurum.
Yörüngedeki Hafiflik Yarışları

2
@JL Sorunun nerede olduğunu göremiyorum. Soyut yöntemi soyut sınıfla karıştırmış görünüyorsunuz. Soyut yöntemlerin uygulanması yoktur. Ancak, soyut bir sınıfın içinde , bazı yöntemler soyut olabilir (yani uygulama olmadan), bazılarında ise gerçekten uygulama olabilir.
xji

19
Java 8'de artık arayüzlerde varsayılan yöntemlere ve statik yöntemlere sahip olabileceğinizi, yani Java arayüzlerinin uygulanabileceğini unutmayın. Burada referans . Açıkçası esas olarak .NET'e başvurdunuz, bu yüzden bu sadece Java'ya atıfta bulunan bir gözlem.
davtom

866

Bir benzetmeye ne dersin: Hava Kuvvetleri'ndeyken pilot eğitimine gittim ve bir USAF (ABD Hava Kuvvetleri) pilotu oldum. Bu noktada hiçbir şey uçmaya uygun değildim ve uçak tipi eğitime katılmak zorunda kaldım. Kalifiye olduktan sonra bir pilot (Soyut sınıf) ve bir C-141 pilot (somut sınıf) oldum. Görevlerimden birinde bana ek bir görev verildi: Güvenlik Görevlisi. Şimdi hâlâ bir pilot ve C-141 pilotuydum, ama aynı zamanda Güvenlik Görevlisi görevlerini de yerine getirdim (tabiri caizse ISafetyOfficer'ı uyguladım). Pilotun güvenlik görevlisi olması gerekmiyordu, diğer insanlar da bunu yapabilirdi.

Tüm USAF pilotları Hava Kuvvetleri çapında belirli düzenlemelere uymak zorundadır ve tüm C-141 (veya F-16 veya T-38) pilotları 'USAF pilotlarıdır. Herkes güvenlik görevlisi olabilir. Özetlemek gerekirse:

  • Pilot: soyut sınıf
  • C-141 Pilot: beton sınıfı
  • Güvenlik Görevlisi: arayüz

ek not: Bu, bir kodlama önerisi değil, kavramı açıklamaya yardımcı olacak bir benzetme anlamına geliyordu. Aşağıdaki çeşitli yorumlara bakın, tartışma ilginçtir.


87
Bu benzetmeyi gerçekten seviyorum, biraz karmaşık bir konuyu açıklamak için basit bir örnek kullanıyor
Kevin Bowersox

13
Karmaşık OO terminolojisini anlamanın en iyi yolu budur. Kısacası, tüm teori sadece onu pratik olarak kullanabileceğiniz zaman değerlidir. @Örneğin, birkaç mermi noktasını kavramak gerçekten kolaydır (emilmek yerine çoğunlukla nüfuz eden zihin!)
vs

54
Hala biraz kafam karıştı. Diyelim ki artık F-16 ve T-38 niteliklerine sahipsiniz, bu yüzden şimdi sınıf Jaybirden fazla sınıftan miras alınamıyor (C-141 pilotu, F-16 pilotu ve T-38 pilotu), bu kimin sınıflarının arabirim olması gerektiği anlamına mı geliyor? Teşekkürler
Alex Okrushko

37
Birçok insan haklı olarak Alex'in yorumuna +1 verdi, çünkü bu örnekte bazı zayıflıklar ortaya koyuyor. İlk olarak, Jay'in kendi sınıfından ziyade C-141Pilot örneği olacağını söyleyebilirim. Buna ek olarak, USAF'de tüm pilotların% 99'u bir seferde sadece bir uçakta kalifiye olduklarından (FCF ve test pilotları dikkate değer istisnalar) birden fazla nitelik ve bunun nasıl uygulanabileceğini düşünmedim. 50 yıl önce aynı anda 25 farklı uçakta kalifiye olan bir pilottan bildiğim gibi, bunun birden fazla miras kullanmak istemediğimizi örneklediğini düşünüyorum.
Jay

20
Bir pilotun bir seferde birden fazla uçak uçması olası olmadığından, strateji modelini uygulamak iyi bir fırsat olacaktır. Pilot uygulama bir sertifika koleksiyonuna sahip olacak ve çalışma zamanında doğru olanı seçecektir. Sertifikalar, TakeOff, Land, Eject yöntemleriyle IFlyPlane arabirimini uygulayacak davranışlar olarak kodlanır.
Michael Blackburn

221

Aradıkları yanıtın temel veya OPPS felsefi farkı olduğunu düşünüyorum.

Soyut sınıf mirası, türetilmiş sınıf, soyut sınıfın temel özelliklerini ve davranışını paylaştığında kullanılır. Sınıfı gerçekten tanımlayan davranış türü.

Öte yandan, sınıflar, türetilmiş sınıfı mutlaka tanımlaması gerekmeyen çevresel davranışları paylaştığında arabirim mirası kullanılır.

Örneğin. Bir Araba ve Kamyon, bir Otomobil soyut sınıfının birçok temel özelliğini ve davranışını paylaşır, ancak aynı zamanda Drillers veya PowerGenerators gibi otomobil dışı sınıfların bile paylaştığı ve mutlaka bir Araba veya Kamyon tanımlamadığı Egzoz üret gibi bazı çevresel davranışları paylaşırlar. , Araba, Kamyon, Driller ve PowerGenerator hepsi aynı IExhaust arayüzünü paylaşabilir.


32
Bence daha iyi bir benzetme , arayüzün sözleşme niteliğini gösterecek olan "usesFuel" olacaktır .
Pureferret

@Pureferret accelerate, Otomobil soyut sınıfının temel davranışının bir parçasıysa accelerate, sözleşme niteliğini gösterir diyemem . sözleşme niteliği nedir? bu kelime neden contractkonuştuğumuzda ortaya çıktı interface?
14'te

@overexchange çünkü tipik olarak arayüz sadece iki 'yüzeyin' buluştuğu yerdedir, ancak sözleşme kelimesi iki 'yüzeyin' nasıl buluştuğuna dair bir anlaşma olduğunu ima eder . Egzoz oluşturmanın 'kabul ettiğiniz' bir şey olduğu (en azından benim için) mantıklı değil. Ama yakıt kullanmaya ihtiyaç duyduğunuzu kabul edersiniz (yine benim için).
Pureferret

1
@Pureferret ben aynı bağlantıda bir sorgu kaldırdı
overexchange

1
@ Periferret interfaceçevresel davranışa ihtiyaç duyarsa , neden public interface List<E> extends Collection<E> {}temel davranışını tanımlamak için tasarlanmıştır list? bu aslında prasun'un cevabı ile çelişiyor. Hem Collection<E>ve List<E>arayüzler burada.
Kasım'da

198

Kısa: Soyut sınıflar Modelleme için kullanılır benzer görünümlü sınıfların sınıf hiyerarşisini (Örneğin Hayvan soyut sınıf olabilir ve İnsan, Aslan, Kaplan somut türetilmiş sınıflar olabilir)

VE

Arabirim, sınıf uygulayan arabirimin türünü önemsemeyen 2 benzer / benzer olmayan sınıf arasındaki iletişim için kullanılır Arabirim (örn. Yükseklik arabirim özelliği olabilir ve İnsan, Bina, Ağaç tarafından uygulanabilir. Yemek yiyip yiyemeyeceğiniz önemli değildir. , ölebilir ya da herhangi bir şey yüzebilirsiniz .. sadece Yükseklik (sınıf uygulama) olması gereken bir şey önemlidir.


7
Bu cevabı gerçekten çok seviyorum çünkü bazen sadece yapı yerine niyet gibi daha soyut bir şeye bakarak şeyler arasındaki "neyin" farklı olduğunu cevaplamak zordur (yapısal olarak, bir arayüz ve saf bir soyut sınıf hemen hemen aynıdır şey).
LostSalad

Soyut bir sınıfın veya bir arabirimin belirli bir dilde ne yapabileceğini numaralandırmak kolaydır, ancak nesneye anlam ve sorumluluk vermek için bir soyutlama oluşturmak ve söylediğiniz şey OO'daki 2 kavramının kullanımını tamamen sürdürmek daha zordur. Teşekkürler!
Samuel

2
@dhananjay: Yüksekliğin Hayvan sınıfı kavramından nasıl ayrı olabileceğini ve başka bir sınıftan nasıl olabileceğini görüyorum, ama sınıflar arasındaki “iletişim” ile tam olarak ne demek istiyorsun? Sadece kendi sınıfı için Yüksekliği tanımlar, değil mi?
TTT

77

Birkaç başka fark daha var -

Arayüzlerin somut uygulamaları olamaz. Soyut temel sınıflar yapabilir. Bu, orada somut uygulamalar sunmanıza olanak tanır. Bu, soyut bir temel sınıfın daha sıkı bir sözleşme sağlamasına izin verebilir, bir arayüz gerçekten sadece bir sınıfın nasıl kullanıldığını açıklar. (Soyut temel sınıf, davranışı tanımlayan ve temel sınıf yazarına daha fazla denetim sağlayan sanal olmayan üyelere sahip olabilir.)

Bir sınıfa birden fazla arabirim uygulanabilir. Bir sınıf yalnızca tek bir soyut temel sınıftan türetilebilir. Bu, arabirimleri kullanarak polimorfik hiyerarşiye izin verir, ancak soyut temel sınıflara izin vermez. Bu aynı zamanda arayüzleri kullanarak sözde çoklu kalıtım sağlar.

Soyut temel sınıflar API'yı bozmadan v2 + 'da değiştirilebilir. Arayüzlerde yapılan değişiklikler değişiklikleri bozuyor.

[C # /. NET Spesifik] Arabirimler, soyut temel sınıflardan farklı olarak, değer türlerine (yapılar) uygulanabilir. Yapılar soyut temel sınıflardan miras alınamaz. Bu, davranış tiplerinin / kullanım kılavuzlarının değer türlerine uygulanmasına izin verir.


5
Bir sınıfa birden fazla arabirimin uygulanabileceği anahtar nokta için +1.
cgp

Soyut temel sınıflar, IMO üzerindeki arayüzlerin gerçek avantajı budur. Aksi takdirde, şimdi "arabirimler üzerinde soyut temel sınıfları tercih etmek" diyen .NET tasarım yönergelerine katılıyorum
Reed Copsey

Bununla birlikte, arayüzlerin herhangi bir sınıfa da uygulanabileceği noktasını ekleyebilirseniz istekli olacaktır.
cgp

1
@altCognito: Bunun ikinci paragrafla ele alındığını düşündüm. Ancak bu, arayüzlerin değer türleri üzerinde çalıştığını hatırlattı, bu yüzden ekledim.
Reed Copsey

Bu tam açıklama için çok teşekkür ederim. Gerçekten çok yararlı. Ben burada yeniyim. "Cevap" olarak iki cevap seçememen üzücü. Beni şaşırtan bir şey Özet 'temel' sınıfını kullanmanızdır. Tüm soyut sınıfların bir alt sınıfın temel sınıfı olması amaçlanmıştır. Neden 'üssü' isimlendirmek?
Houman

68

Kalıtım
Bir araba ve bir otobüs düşünün. Bunlar iki farklı araç. Ama yine de, direksiyon, fren, vites, motor vb.Gibi bazı ortak özellikleri paylaşıyorlar.
Bu yüzden miras konseptiyle, bu aşağıdaki gibi temsil edilebilir ...

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Şimdi bir bisiklet ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

Ve bir Araba ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

Hepsi miras . Nesneleri yukarıda gördüğümüz gibi daha basit Temel formlara ve çocuklarına sınıflandırmak için kullanırız.

Soyut Sınıflar

Soyut sınıflar eksik nesnelerdir. Daha fazla anlamak için, araç benzetmesini bir kez daha düşünelim.
Bir araç sürülebilir. Sağ? Ancak farklı araçlar farklı şekillerde sürülür ... Örneğin, bir Bisiklet sürerken araba kullanamazsınız.
Peki bir aracın sürüş fonksiyonunu nasıl temsil edebilirim? Ne tür bir araç olduğunu kontrol etmek ve kendi işlevi ile sürmek daha zordur; yeni bir araç türü eklerken Driver sınıfını tekrar tekrar değiştirmeniz gerekecektir.
İşte soyut sınıfların ve yöntemlerin rolü geliyor. Sürüş yöntemini, miras alan her çocuğun bu işlevi uygulaması gerektiğini söylemek için soyut olarak tanımlayabilirsiniz.
Araç sınıfını değiştirirseniz ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

Bisiklet ve Araba da nasıl kullanılacağını belirtmelidir. Aksi takdirde, kod derlenmez ve bir hata atılır.
Kısacası, soyut bir sınıf, miras kalan çocukların kendilerinin belirtmesi gereken bazı eksik işlevlere sahip kısmen tamamlanmamış bir sınıftır.

Arayüzler Arayüzler tamamen eksiktir. Herhangi bir özelliği yoktur. Sadece miras kalan çocukların bir şeyler yapabildiklerini gösteriyorlar ...
Diyelim ki yanınızda farklı türde cep telefonları var. Her birinin farklı işlevler yapmak için farklı yolları vardır; Örn: bir kişiyi arayın. Telefonun üreticisi, nasıl yapılacağını belirler. Burada cep telefonları bir numara çevirebilir - yani, çevrilebilir. Bunu bir arayüz olarak gösterelim.

public interface Dialable {
    public void dial(Number n);
}

Burada, Dialable'ın bir numarası nasıl aranacağını tanımlar. Sadece çevirmek için bir numara vermeniz gerekiyor.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Bu vesileyle, soyut sınıflar yerine arayüzler kullanarak, bir Dialable kullanan fonksiyonun yazarının özellikleri hakkında endişelenmesine gerek yoktur. Örn: Dokunmatik ekran veya tuş takımı var mı, Sabit bir sabit telefon mu yoksa cep telefonu mu? Sadece diyalog olup olmadığını bilmeniz gerekir; Dialable arabirimini devralır (veya uygular).

Ve daha da önemlisi , bir gün Dialable'ı farklı biriyle değiştirirseniz

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Kodun hala mükemmel şekilde çalıştığından emin olabilirsiniz çünkü dialable'ı kullanan işlev, Dialable arabiriminde belirtilenlerin dışındaki ayrıntılara bağlı değildir (ve olamaz). Her ikisi de bir Dialable arabirimi uygular ve işlevin önem verdiği tek şey budur.

Arayüzler, ortak bir işlevi paylaştıkları sürece (tıpkı bir numarayı çevirmeniz gerektiği sürece, sabit hatlara veya cep telefonlarına geçebildiğiniz gibi) nesneler arasında birlikte çalışabilirlik (birbirinin yerine kullanılabilir) sağlamak için geliştiriciler tarafından yaygın olarak kullanılır. Kısacası, arayüzler herhangi bir özellik olmadan soyut sınıfların çok daha basit bir versiyonudur.
Ayrıca, istediğiniz kadar arabirim uygulayabileceğinizi (devralabileceğiniz) ancak yalnızca tek bir üst sınıfı genişletebileceğiniz (devralabileceğiniz) unutmayın.

Daha Fazla Bilgi Soyut sınıflar ve Arayüzler


"Arayüzlerin herhangi bir özelliği olmadığı" doğru değildir.
Bigeyes

@Bigeyes, java arabirimlerdeki özelliklere izin vermez. Diğer dillerde de aynı olduğunu düşündüm. Daha fazla açıklayabilir misiniz?
fz_salam

C # /. Net'e atıfta bulunuyorum. Lütfen örneğe
Bigeyes

Arabirimlerin özelliklere sahip olabileceği C # için @Bigeyes, bu çoklu kalıtım sorununu yeniden oluşturmuyor mu? Bir sınıf aynı özelliği tanımlayan birden fazla arabirim kullandığında ne olur? Just curious thanks
stackPusher

@happycoder: re: "Burada soyut sınıflar yerine arayüzler kullanarak özellikleri hakkında endişelenmenize gerek yok. Örn: Dokunmatik ekran veya tuş takımı var mı, sabit bir sabit telefon mu yoksa cep telefonu mu? aratılabilir olup olmadığını bilmek; Arayatılabilir arabirimi miras alır (veya uygular). " - Bunu bir kod örneğinde gösterebilir misiniz, aynı zamanda nasıl miras alınacağını da görmediniz ...
TTT

45

Eğer düşünürsen javaBu soruyu cevaplamak için OOP dili olarak , Java 8 sürümü yukarıdaki yanıtlardaki içeriğin bir kısmının eski olmasına neden olur. Şimdi java arayüzü somut uygulama ile varsayılan yöntemlere sahip olabilir.

Oracle web sitesiinterface ve abstractsınıf arasındaki önemli farkları sağlar .

Aşağıdaki durumlarda soyut sınıfları kullanmayı düşünün :

  1. Kodu yakından ilişkili birkaç sınıf arasında paylaşmak istiyorsunuz.
  2. Soyut sınıfınızı genişleten sınıfların birçok ortak yöntemi veya alanı olmasını veya genel (erişim korumalı ve özel gibi) dışında erişim değiştiricileri gerektirmesini beklersiniz.
  3. Statik olmayan veya son olmayan alanları bildirmek istiyorsunuz.

Aşağıdaki durumlarda arayüzleri kullanmayı düşünün :

  1. İlişkisiz sınıfların arayüzünüzü uygulamasını beklersiniz. Örneğin, ilgisiz birçok nesne Serializablearabirim uygulayabilir .
  2. Belirli bir veri türünün davranışını belirtmek istiyorsunuz, ancak davranışını kimin uyguladığından endişe etmiyorsunuz.
  3. Birden fazla tür mirasından yararlanmak istiyorsunuz.

Basit bir ifadeyle, kullanmak istiyorum

arayüz: İlişkisiz birden çok nesne tarafından bir sözleşme uygulamak

soyut sınıf: Aynı veya farklı davranışı birden çok ilişkili nesne arasında uygulamak için

Olayları net bir şekilde anlamak için kod örneğine bir göz atın: Bir Arabirim ile Soyut bir sınıf arasındaki farkı nasıl açıklamalıydım?


33

Görüşmeciler tuhaf bir ağaç havlıyor. C # ve Java gibi diller için bir fark vardır, ancak C ++ gibi diğer dillerde de yoktur. OO teorisi ikisini, sadece dilin sözdizimini ayırt etmez.

Soyut bir sınıf, miras alınacak olan hem uygulamaya hem de arayüze (saf sanal yöntemler) sahip bir sınıftır. Arayüzler genellikle herhangi bir uygulamaya sahip değildir, sadece saf sanal işlevlere sahiptir.

C # veya Java'da, herhangi bir uygulaması olmayan soyut bir sınıf, yalnızca ondan miras almak için kullanılan sözdizimindeki bir arabirimden ve yalnızca birinden miras alabileceğinizden farklıdır.


Aynı soruyu bir hafta önce sordum, Java ile hiçbir deneyimim yok ama bir süredir C ++ ile çalışıyorum. Görüşmeci, soruyu sormadan önce dil belirtmedi, bu yüzden bu durumda arayüzlerin devlet veya herhangi bir tür uygulaması olmayan soyut sınıflar olduğunu açıkladım. Bunun da garip bir soru olduğunu kabul ediyorum.
dacabdi

31

Arabirimler uygulayarak kalıtım ("is-a" ilişkileri) yerine kompozisyon ("has-a" ilişkileri) elde edersiniz. Bu, kalıtım yerine davranışların bir bileşimini elde etmek için arayüzler kullanmanız gereken tasarım desenleri gibi şeyleri hatırlamak için önemli bir ilkedir.


17
Arayüzler, IMO, daha çok bir "gibi davranır" ilişkisine ulaşır. Kapsülleme, bileşime bir arayüzden daha iyi ulaşır.
Reed Copsey

12
Uygulama arayüzlerinin kompozisyon altına gireceğini düşünmüyorum.
Pavan Dittakavi

Ayrıca, arayüz daha çok IDisposable gibi "yetenek" tanımlamak için kullanın. Bu sınıfların bir şey "yapabildiği" sınıflar arasındaki işlevselliği paylaşmak için kullanılır. Daha fazla örnek IFlyable, kuş ve uçak tarafından uygulanabilir. Ancak Bird, hava aracının AirCraft'tan türediği Class Creature'dan türetilebilir.
Peter.Wang

26

Arayüz ve Soyut sınıfın Derinlik Ayrıntılarını açıklayacağım. arayüz ve soyut sınıf hakkında genel bir bakış biliyorsanız, ilk soru ne zaman Arayüz kullanmamız gerektiğinde ve Soyut sınıf kullanmamız gerektiğinde aklınıza gelir. Lütfen aşağıdaki Arayüz ve Soyut sınıf açıklamalarını kontrol edin.

  1. Interface'i ne zaman kullanmalıyız?

    Eğer uygulama hakkında bilmiyorsanız, sadece şartname belirtimimiz var, o zaman Arayüz ile gidiyoruz

  2. Abstract Class'ı ne zaman kullanmalıyız?

    Eğer uygulamayı biliyor ama tamamen (kısmen uygulama) bilmiyorsanız, o zaman Abstract sınıfına gidiyoruz.

    Arayüz

    her yöntem varsayılan olarak genel soyut arayüz% 100 saf soyut demektir.

    Öz

    Somut yöntem ve Soyut yöntem olabilir, Soyut sınıfta uygulaması olan Somut yöntem, Soyut bir sınıf soyut olarak ilan edilen bir sınıftır - soyut yöntemleri içerebilir veya içermeyebilir.

    Arayüz

    Özel, korumalı bir arayüz olarak ilan edemeyiz

    S. Interface'i neden özel ve korumalı ilan etmiyoruz?

    Çünkü varsayılan olarak arabirim yöntemi genel özettir ve bu nedenle arabirimi özel ve korumalı olarak ilan etmiyoruz.

    Arayüz yöntemi
    de arayüz olarak özel, korumalı, nihai, statik, senkronize, yerli olarak ilan edemeyiz .....

    neden verecektir: neden biz arabirim nesnesi oluşturamazsınız ve senkronize nesne üzerinde çalışmak ve bu nedenle senkronize yöntemi bildirmiyoruz oğlu nedeni geçici senkronize ile geçici çalışma geçerli değildir çünkü neden senkronize yöntem beyan etmiyoruz.

    Öz

    mutlu, kamuya açık, özel nihai statik ile kullanıyoruz .... soyutta herhangi bir kısıtlama olmadığı anlamına gelir.

    Arayüz

    Değişkenler, varsayılan olarak genel statik final olarak Arabirim'de bildirildiğinden, değişken olarak özel, korumalı olarak bildirilmez.

    Arabirim değişkeni varsayılan olarak genel statik son ve son değişken olduğundan, değişken değişkeni de arabirim için geçerli değildir. Değeri değişkene atadıktan sonra değeri değiştiremezsiniz ve değişkeni arabirime bildirdikten sonra değişkeni atamanız gerekir.

    Ve değişken değişken değişikliklere devam ediyor, bu yüzden opp. bu yüzden arayüzde uçucu değişken kullanmıyoruz.

    Öz

    Soyut değişken kamu statik final ilan etmek gerek yok.

Umarım bu makale faydalıdır.


4
Bu noktaya katılmıyorum: Abstract class must have at lease one abstract method.Uyguladığınız sürece, Abstract yöntemi olmayan bir Abstract sınıfına sahip olmak mümkündür. REFERANS: An abstract class is a class that is declared abstract—it may or may not include abstract methods.REFERANS KAYNAĞI: docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Devner

Teknik detaylar ve uygulama hakkında konuşuyorsunuz, soruyu genel OOP açısından cevaplamıyorsunuz
Billal Begueradj

26

Kavramsal olarak konuşmak, dile özgü uygulama, kurallar, faydalar sağlamak ve herhangi birini veya her ikisini kullanarak herhangi bir programlama hedefine ulaşmak, kod / veri / mülk, falan filan, tek veya çoklu mirasa sahip olabilir veya olamaz

1- Soyut (ya da saf soyut) Sınıf hiyerarşiyi uygulamak içindir. İş nesneleriniz yapısal olarak benzer görünüyorsa, sadece bir ebeveyn-çocuk (hiyerarşi) tür ilişkisini temsil eden miras / Soyut sınıflar kullanılacaktır. İş modelinizde bir hiyerarşi yoksa, kalıtım kullanılmamalıdır (burada programlama mantığından bahsetmiyorum, örneğin bazı tasarım kalıpları kalıtım gerektirir). Kavramsal olarak soyut sınıf, OOP'de bir iş modeli hiyerarşisini uygulamak için bir yöntemdir, Arayüzlerle hiçbir ilgisi yoktur, aslında Soyut sınıfı Arayüz ile karşılaştırmak anlamsızdır, çünkü her ikisi de kavramsal olarak tamamen farklı şeylerdir, görüşmelerde sadece kavramları kontrol etmesi istenir, çünkü uygulama söz konusu olduğunda hem aynı işlevsellik sağlar hem de programcılar genellikle kodlama üzerinde daha fazla vurgu yaparız. [Soyutlamanın Soyut Sınıftan farklı olduğunu da aklınızda bulundurun].

2- Arayüz, bir sözleşme veya bir veya daha fazla işlev grubu tarafından temsil edilen eksiksiz bir iş işlevselliğidir. Bu yüzden uygulanır ve kalıtsal değildir. Bir iş nesnesi (bir hiyerarşinin parçası olsun olmasın) herhangi bir sayıda tam işlevsellik içerebilir. Soyut sınıflarla hiçbir ilgisi yoktur, genel olarak kalıtım anlamına gelir. Örneğin, bir insan RUN yapabilir, bir fil RUN yapabilir, bir kuş RUN yapabilir ve böylece, farklı hiyerarşideki tüm bu nesneler RUN arabirimini veya EAT veya SPEAK arabirimini uygular. Bu arabirimleri uygulayan her tür için soyut sınıflara sahip olarak uygulayabileceğiniz için uygulamaya geçmeyin. Herhangi bir hiyerarşinin bir nesnesi, hiyerarşisiyle ilgisi olmayan bir işlevselliğe (arayüze) sahip olabilir.

İnanıyorum ki, Arayüzler birden fazla miras elde etmek veya kamu davranışını ortaya çıkarmak için icat edilmedi ve benzer şekilde saf soyut sınıflar arayüzleri geçersiz kılmak için değil, Arayüz bir nesnenin yapabileceği bir işlevselliktir (bu arayüzün işlevleri aracılığıyla) ve Soyut Sınıf bir ebeveynin çekirdek yapısına (özellik + işlevsellik) sahip çocuklar üretmek için bir hiyerarşinin üst öğesi

Fark size sorulduğunda, açıkça sorulmadıkça, dile özgü uygulamadaki fark değil, aslında kavramsal farktır.

Her iki görüşmeci de, bu ikisi arasında bir satır doğrudan fark bekliyorduk ve başarısız olduğunuzda, ONE'u DİĞER olarak uygulayarak sizi bu farklılığa sürüklemeye çalıştılar.

Ya sadece soyut yöntemlerle bir Abstract dersiniz olsaydı?


Bu sorunun cevabını oldukça iyi özetliyor.
pranavn

yapıya karşı işlevsellik genişletilmiş, güzel!
harshvchawla

21

.Net için,

İkinci görüşmeci için cevabınız da birincinin cevabıdır ... Soyut sınıfların uygulaması olabilir, VE devlet, arayüzler olamaz ...

EDIT: Başka bir not, 'arabirimi uygulamak için tanımlanmış' sınıfları tanımlamak için 'alt sınıf' (veya 'miras' deyimi) deyimini bile kullanmaz. Benim için bir arabirim, bir sınıfın o arabirimi 'uygulamak' için tanımlanmışsa uyması gereken bir sözleşmenin tanımıdır. Hiçbir şey miras almaz ... Her şeyi açıkça eklemeniz gerekir.


2
Evet! Durum! Bu, ikinci görüşmecinin bir arayüzün içinde "kamu değişkeni" demenin garip yolu ile kastettiği şeydi. Allah Allah! Özet Sınıflar durum alabilir, arayüzler olamaz! Ve evet, herkes, miras yolları arasındaki farkları da kabul ediyor, bu da bahsetmeyi unuttuğum ama daha sonra anladım. :) Herkese teşekkürler!
Houman

4
Devletten daha fazlası ... Soyut sınıflar UYGULAMA yapabilir. yani aslında çalışır ve O kadar arayüzleri ile taban sınıfların örneklerini ... tarafından inhertited ve işletilirse şey yapar onları koduyla yöntemleri olabilir
Charles Bretana

Bundan da öte, bir anlamda, Soyut sınıflar somutlaştırılabilir, doğrudan değil türetilmiş bir sınıf tanımı kullanılarak somutlaştırılmalıdır. Ancak, soyut sınıfta tanımlanan durum değişkenleri, türetilmiş sınıfın bir örneğinin yeniden oluşturulmasıyla oluşturulan nesnede somutlaştırılır. Bu örnek, soyut sınıfın bir örneğidir ve türetilmiş sınıfın bir örneğidir - sonuçta ondan türetilir. Bunların hiçbiri bir arayüz için geçerli değildir.
Charles Bretana

Bir arabirimi uygulamak üzere tanımlanmış bir sınıf örneğini yeniden oluşturduğunuzda, bu arabirimin bir "örneği" değildir; tüm sözdizimi, derleyicinin sınıfın kodunu incelemesine ve her davranışın (yöntem, özellik) , event, eventHandler, vb.) arabirim tarafından tanımlanan sınıf kodunda uygulanmıştır.
Charles Bretana

20

Arabirim : Bileşenler üzerinde birbiriyle ilişkili olan veya olmayan bir kural belirtmek istiyorsanız kullanılmalıdır

Artıları:

  1. Birden fazla mirasa izin verir
  2. Bağlamda ne tür bir nesnenin kullanıldığını göstermeyerek soyutlama sağlar
  3. sözleşmenin belirli bir imzası ile tutarlılık sağlar

Eksileri:

  1. Tanımlanan tüm sözleşmeleri uygulamalıdır
  2. Değişkenler veya temsilciler olamaz
  3. Tanımlandıktan sonra tüm sınıfları bozmadan değiştirilemez

Soyut Sınıf : birbiriyle ilişkili bileşenler için bazı temel veya varsayılan davranış veya uygulamalara sahip olmak istediğiniz yerde kullanılmalıdır

Artıları:

  1. Arayüzden daha hızlı
  2. Uygulamada esnekliğe sahiptir (tamamen veya kısmen uygulayabilirsiniz)
  3. Türetilmiş sınıfları bozmadan kolayca değiştirilebilir

Eksileri:

  1. Örneklenemez
  2. Birden fazla mirası desteklemiyor

Daha hızlı tanımlayın. Önemli mi? Bu ne anlama geliyor? soyut bir sınıfta işlev çağırma opcode bir arayüzde işlev çağırma opcode daha hızlı?
denis631

@ denis631 soyut sınıf, arama ve çağrı arabirim yöntemine dahil olduğu için arayüzden biraz daha hızlıdır. bu kodu okuyunranch.com/t/503450/java/abstract-class-faster-interface
bourax webmaster

17

Sanırım yanıtınızı beğenmediler çünkü tasarım yerine teknik farklılıklar verdiniz. Soru benim için bir trol sorusu gibi. Aslında, arayüzler ve soyut sınıflar tamamen farklı bir doğaya sahiptir, bu yüzden onları gerçekten karşılaştıramazsınız. Size bir arayüzün rolü ve soyut bir sınıfın rolü hakkında vizyonumu vereceğim.

arayüz: Daha sürdürülebilir, ölçeklenebilir ve test edilebilir bir uygulamaya sahip olmak için bir sözleşme sağlamak ve sınıflar arasında düşük bir bağlantı yapmak için kullanılır.

soyut sınıf: sadece aynı sorumluluktaki sınıflar arasındaki bazı kodları çarpanlarına ayırmak için kullanılır. Bir sınıfın birçok sorumluluğu ele almaması gerektiğinden , çoklu kalıtımın OOP'de kötü bir şey olmasının ana nedeni olduğunu unutmayın ( kompozisyon kullanın) bunun yerine kullanın).

Bu nedenle arayüzler gerçek bir mimari role sahiptir, oysa soyut sınıflar neredeyse sadece uygulamanın bir detayıdır (tabii ki doğru kullanırsanız).


13
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

Belgeler , soyut bir sınıf yalnızca soyut yöntem bildirimleri içeriyorsa bunun yerine bir arabirim olarak bildirilmesi gerektiğini açıkça göstermektedir.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Arabirimlerdeki değişkenler varsayılan olarak genel statik ve son değerlerdir. Soru, soyut sınıftaki tüm değişkenler halka açıksa ne gibi çerçevelenebilir? Arayüzlerdeki değişkenlerin aksine hala statik ve nihai olmayabilirler.

Son olarak, yukarıda belirtilenlere bir nokta daha ekleyeceğim - soyut sınıflar hala sınıflar ve tek bir miras ağacına düşerken, arayüzler çoklu mirasta mevcut olabilir.


13
  1. Arayüz:
    • Yöntemleri uygulamıyoruz (veya tanımlamıyoruz), bunu türetilmiş sınıflarda yapıyoruz.
    • Arayüzlerde üye değişkenleri beyan etmiyoruz.
    • Arayüzler HAS-A ilişkisini ifade eder. Bu, nesnelerin maskesi oldukları anlamına gelir.
  2. Soyut sınıf:
    • Soyut sınıfta yöntemleri açıklayabilir ve tanımlayabiliriz.
    • Yapıcılarını gizliyoruz. Bu, ondan doğrudan yaratılmış bir nesne olmadığı anlamına gelir.
    • Soyut sınıf üye değişkenleri tutabilir.
    • Türetilmiş sınıflar, türetilmiş sınıflardan nesnelerin maskelenmediği, soyut sınıfa miras aldığı soyut sınıfa miras kalır. Bu durumda ilişki IS-A'dır.

Bu benim görüşüm.


12

CLR'den Jeffrey Richter tarafından C # ile kopyalandı ...

Sık sık, “Temel tip mi yoksa arayüz mü tasarlamalıyım?” Sorusunu duyuyorum. Cevap her zaman net değildir.

Size yardımcı olabilecek bazı yönergeler şunlardır:

■■ IS-A ve CAN-DO ilişkisi Bir tür yalnızca bir uygulamayı devralabilir. Türetilmiş tip temel tiple bir IS-A ilişkisi talep edemezse, temel tip kullanmayın; bir arayüz kullanın. Arayüzler bir CAN-DO ilişkisi anlamına gelir. CAN-DO işlevi çeşitli nesne türlerine ait gibi görünüyorsa, bir arabirim kullanın. Örneğin, bir tür kendi örneklerini başka bir türe dönüştürebilir (IConvertible), bir tür kendi örneğini serileştirebilir (ISerializable), vb. keyfi bir taban sınıftan. Bu durumda, bir CAN-DO ilişkisi kullanmalı ve bir arabirim tanımlamalısınız.

■■ Kullanım kolaylığı Bir geliştirici olarak, bir taban türünden türetilen yeni bir tür tanımlamanız genellikle bir arabirimin tüm yöntemlerini uygulamaktan daha kolaydır. Temel tür çok fazla işlevsellik sağlayabilir, bu nedenle türetilmiş tür muhtemelen davranışında nispeten küçük değişikliklere ihtiyaç duyar. Bir arabirim sağlarsanız, yeni türün tüm üyeleri uygulaması gerekir.

■■ Tutarlı uygulama Bir arayüz sözleşmesi ne kadar iyi belgelenirse dökülsün, herkesin sözleşmeyi yüzde 100 doğru bir şekilde uygulaması pek olası değildir. Aslında, COM bu sorundan muzdarip, bu nedenle bazı COM nesneleri yalnızca Microsoft Word veya Windows Internet Explorer ile düzgün çalışır. İyi bir varsayılan uygulamaya sahip bir taban türü sağlayarak, çalışan ve iyi sınanmış bir türü kullanmaya başlarsınız; daha sonra modifikasyon gerektiren parçaları değiştirebilirsiniz.

■■ Sürüm Oluşturma Temel türe bir yöntem eklerseniz, türetilmiş tür yeni yöntemi devralır, çalışan bir tür kullanmaya başlarsınız ve kullanıcının kaynak kodunun yeniden derlenmesi gerekmez. Bir arabirime yeni bir üye eklemek, arabirimin mirasçısını kaynak kodunu değiştirmeye ve yeniden derlemeye zorlar.


1
@AbdullahShoaib-a ve herkes-yapabilir ama yapamaz, burada bir fark var. temel nedeni bu, arayüze ihtiyacımız var. yapabilirim davranışı da bir parçası olacaktır abstract class.
Kasım'da aşırı döviz değişimi

10

Bir arabirim, bir hizmet veya hizmet kümesi için bir sözleşme tanımlar. İki tamamen ilişkisiz sınıfın aynı arabirimi uygulayabilmeleri, ancak her iki sınıfın arabirim tarafından tanımlanan hizmetler kümesini karşılayacağına söz verdikleri için, uyguladıkları arabirim türünün bir parametresi olarak birbirlerinin yerine kullanılabilecekleri için polimorfizmi yatay bir şekilde sağlarlar. Arabirimler uygulama ayrıntıları sağlamaz.

Soyut bir sınıf, alt sınıfları ve isteğe bağlı olarak kısmi uygulama için bir temel yapı tanımlar. Soyut sınıflar, soyut sınıfı devralan herhangi bir sınıfın, o soyut sınıfın bir örneği olarak ele alınabileceği ancak tersi yönde değil, dikey fakat yönlü bir şekilde polimorfizm sağlar. Soyut sınıflar genellikle uygulama ayrıntılarını içerebilir ve içerebilir, ancak kendi başlarına somutlaştırılamazlar - yalnızca alt sınıfları "yenileştirilebilir".

C #, arabirim mirasına da izin verir, unutmayın.


1
Yatay ve dikey terimlerini kullanmak, farkı hayal etmeyi çok netleştirdi.
Infinity

10

Çoğu cevap Özet Sınıf ve Arayüz arasındaki teknik farka odaklanır , ancak teknik olarak, bir arayüz temel olarak bir tür soyut sınıf (herhangi bir veri veya uygulama olmadan) olduğundan, kavramsal farkın çok daha ilginç olduğunu düşünüyorum ve bu ne olabilir görüşmeciler peşinde.

Bir Arayüz bir olduğunu anlaşması . Şöyle belirtir: "birbirimizle bu şekilde konuşacağız". Herhangi bir uygulaması olamaz çünkü herhangi bir uygulaması olması gerekmez. Bu bir sözleşme. Gibi.h C. başlık dosyaları

Bir Özet Sınıf bir olan tamamlanmamış uygulama . Bir sınıf bir arabirim uygulayabilir veya uygulamayabilir ve soyut bir sınıfın onu tam olarak uygulaması gerekmez. Herhangi bir uygulaması olmayan soyut bir sınıf bir tür yararsızdır, ancak tamamen yasaldır.

Temel olarak soyut ya da soyut herhangi bir sınıf, ne olduğu ile ilgilidir , bir arayüz ise onu nasıl kullandığınızla ilgilidir . Örneğin: Animalbazı temel metabolik fonksiyonları uygulayan ve bir uygulama yapmadan solunum ve hareket için soyut yöntemler belirten soyut bir sınıf olabilir, çünkü solungaçlardan veya akciğerlerden nefes alması gerekip gerekmediği ve uçup, yüzdüğü, yürüdüğü veya tarar. MountÖte yandan, ne tür bir hayvan olduğunu (veya bir hayvan olup olmadığını) bilmeden hayvana binebileceğinizi belirten bir Arayüz olabilir.

Perde arkasında bir arayüzün temelde sadece soyut yöntemlerle soyut bir sınıf olması, önemli değil. Kavramsal olarak, tamamen farklı rolleri doldururlar.


10

Uzmanlardan teorik bilgi edinebileceğiniz için, buradakilerin hepsini tekrarlamak için fazla kelime harcamıyorum, bunun yerine Interfaceve kullanabileceğimiz / kullanamayacağımız basit bir örnekle açıklayayım Abstract class.

Otomobil'in tüm özelliklerini listelemek için bir uygulama tasarladığınızı düşünün. DigitalFuelMeter, Klima, Koltuk ayarı gibi bazı özellikler tüm arabalar için ortak olduğundan, çeşitli noktalarda ortak kalıtım gerekir. Benzer şekilde, sadece Fren sistemi (ABS, EBD) gibi bazı özellikler yalnızca bazı otomobiller için geçerli olduğundan, bazı sınıflar için mirasa ihtiyacımız vardır.

Aşağıdaki sınıf tüm otomobiller için temel sınıf görevi görür:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Her Otomobil için ayrı bir sınıfımız olduğunu düşünün.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Verna ve Cruze otomobilleri için Frenleme teknolojisini miras almak için bir yönteme ihtiyacımız olduğunu düşünün (Alto için geçerli değildir). Her ikisi de fren teknolojisini kullanmasına rağmen, "teknoloji" farklıdır. Bu nedenle, yöntemin Özet olarak ilan edileceği ve alt sınıflarında uygulanması gereken soyut bir sınıf yaratıyoruz.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Şimdi bu soyut sınıftan miras kalmaya çalışıyoruz ve Verna ve Cruze'de fren sistemi tipi uygulanıyor:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

Yukarıdaki iki sınıftaki sorunu görüyor musunuz? Yöntem çocuklarda uygulansa bile C # .Net'in izin vermediği birden çok sınıftan miras alırlar. Burada Arayüz ihtiyacı geliyor.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

Ve uygulama aşağıda verilmiştir:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Şimdi Verna ve Cruze, Interface'in yardımıyla kendi fren sistemleriyle birden fazla kalıtım elde edebilir.


4
Bu, örnekler nedeniyle en iyi açıklamalardan biridir.
Adam Mendoza

2
Bu, beyni sarsmadan benim için anlamlı. Sadece öğrencilerim için bir araba örneği bulmaya çalışıyordum. Bunu bir araya getirmek için zaman ayırdığınız için teşekkürler.
tazboy

9

Arayüzler, belirli bir davranışı zorlamanın hafif yoludur. Düşünmenin bir yolu bu.


8

Bu cevapların hepsi çok uzun.

  • Arayüzler davranışları tanımlamak içindir.

  • Soyut sınıflar, davranışları da dahil olmak üzere bir şeyin kendisini tanımlamak içindir. Bu yüzden bazen bir arabirimi miras alan bazı ekstra özelliklere sahip soyut bir sınıf yaratırız.

Bu ayrıca Java'nın neden sınıflar için yalnızca tek mirası desteklediğini, ancak arabirimlere herhangi bir kısıtlama getirmediğini de açıklar. Çünkü somut bir nesne farklı şeyler olamaz, ama farklı davranışları olabilir.


7

1) Bir arayüz saf bir Soyut Sınıf olarak görülebilir, aynıdır, ancak buna rağmen, bir arayüz uygulamak ve soyut bir sınıftan miras almak aynı değildir. Bu saf soyut sınıftan miras aldığınızda, bir hiyerarşi -> kalıtım tanımlarsınız, eğer arabirimi uygularsanız ve istediğiniz kadar çok arabirim uygulayabilirsiniz, ancak yalnızca bir sınıftan miras alabilirsiniz.

2) Arabirimde bir özellik tanımlayabilirsiniz, böylece o arabirimi uygulayan sınıfın bu özelliğe sahip olması gerekir.

Örneğin:

  public interface IVariable
  {
      string name {get; set;}
  }

Bu arabirimi uygulayan sınıfın böyle bir özelliğe sahip olması gerekir.


7

Bu soru oldukça eski olmasına rağmen, arayüzler lehine bir nokta daha eklemek istiyorum:

Arabirimler, herhangi bir Bağımlılık Enjeksiyon aracı kullanılarak enjekte edilebilir;


1
Bir DI aracının bir arabirimi uygulayan bir sınıfı enjekte edebileceğini kastettiğine inanıyorum. Bu tür araçlardan bazıları soyut bir sınıftan türetilen sınıfları da enjekte edebilir mi yoksa bunun imkansız olduğunu mu söylüyorsunuz?
John Saunders

6

Bir başka cevabımdan , çoğunlukla birini diğerine karşı ne zaman kullanacağımla ilgili:

Deneyimlerime göre, arabirimler en iyi, her birinin aynı yöntem veya yöntemlere yanıt vermesi gereken birkaç sınıfınız olduğunda kullanılır, böylece bu sınıfların ortak arabirimine karşı yazılacak diğer kodlarla birbirlerinin yerine kullanılabilirler. Bir arabirimin en iyi kullanımı, protokolün önemli olduğu, ancak temel mantık her sınıf için farklı olabileceğidir. Aksi takdirde mantığı çoğaltırsanız, bunun yerine soyut sınıfları veya standart sınıf mirasını düşünün.


6

Arabirim Türleri ve Soyut Temel Sınıflar

Pro C # 5.0 ve .NET 4.5 Framework'ten uyarlanmıştır kitabından .

Arabirim türü, soyut bir temel sınıfa çok benzeyebilir. Bir sınıf soyut olarak işaretlendiğinde, türetilmiş tüm türlere polimorfik bir arayüz sağlamak için herhangi bir sayıda soyut üye tanımlayabileceğini hatırlayın. Bununla birlikte, bir sınıf bir dizi soyut üye tanımlasa bile, herhangi bir sayıda kurucu, alan verisi, soyut olmayan üye (uygulama ile) ve benzeri tanımlamak da ücretsizdir. Arayüzler ise sadece soyut üye tanımlarını içerir. Soyut bir ana sınıf tarafından oluşturulan polimorfik arayüz, büyük bir sınırlamadan muzdariptir, çünkü yalnızca türetilen türler, soyut ana baba tarafından tanımlanan üyeleri desteklemektedir. Ancak, daha büyük yazılım sistemlerinde, System.Object dışında ortak bir üst öğeye sahip olmayan birden çok sınıf hiyerarşisi geliştirmek çok yaygındır. Soyut bir temel sınıftaki soyut üyelerin yalnızca türetilmiş türler için geçerli olduğu göz önüne alındığında, farklı hiyerarşilerdeki türleri aynı polimorfik arayüzü desteklemek üzere yapılandırmanın bir yolu yoktur. Örnek olarak, aşağıdaki soyut sınıfı tanımladığınızı varsayalım:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Bu tanım verildiğinde, yalnızca CloneableType öğesini genişleten üyeler Clone () yöntemini destekleyebilir. Bu temel sınıfı genişletmeyen yeni bir sınıf kümesi oluşturursanız, bu polimorfik arabirimi elde edemezsiniz. Ayrıca, C # 'ın sınıflar için çoklu kalıtımı desteklemediğini hatırlayabilirsiniz. Bu nedenle, bir Araba ve bir CloneableType olan bir MiniVan oluşturmak istiyorsanız, bunu yapamazsınız:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Tahmin edebileceğiniz gibi, arayüz tipleri kurtarmaya geliyor. Bir arabirim tanımlandıktan sonra, herhangi bir sınıf veya yapı tarafından, herhangi bir hiyerarşide, herhangi bir ad alanı veya herhangi bir derleme (herhangi bir .NET programlama dilinde yazılmış) içinde uygulanabilir. Gördüğünüz gibi, arayüzler oldukça polimorfiktir. Sistem ad alanında tanımlanan ICloneable adlı standart .NET arabirimini düşünün. Bu arayüz Clone () adında tek bir yöntem tanımlar:

public interface ICloneable
{
object Clone();
}

6

İkinci soruya Cevap: publictanımlanan değişken interfaceolduğu static finalsüre varsayılan olarak publicdeğişken abstractsınıfının bir örnek değişkendir.


6

Elbette OOP'ta arayüzün ve soyut sınıfın davranışını (ve dillerin onları nasıl ele aldığını) anlamak önemlidir, ancak her terimin tam olarak ne anlama geldiğini anlamak da önemlidir. Hayal edebiliyor musunifKomutun, terimin anlamı olarak tam olarak çalışmadığını musunuz? Ayrıca, aslında bazı diller, bir arayüz ve bir soyut arasındaki farkları daha da azaltmaktadır ... şans eseri bir gün iki terim neredeyse aynı şekilde çalışırsa, en azından kendinizi nerede (ve neden) herhangi birinin nerede olması gerektiğini tanımlayabilirsiniz için kullanılır.

Bazı sözlükleri ve diğer yazı tiplerini okursanız, aynı terim için farklı anlamlar bulabilir, ancak bazı ortak tanımları bulabilirsiniz. Bu sitede bulduğum bu iki anlamın gerçekten çok iyi ve uygun olduğunu düşünüyorum.

Arayüz:

Ayrı ve bazen uyumsuz öğelerin etkin bir şekilde koordine edilmesini sağlayan bir şey veya durum.

Öz:

Daha geniş veya daha genel bir şeyin veya birkaç şeyin temel niteliklerini kendi içinde yoğunlaştıran bir şey; öz.

Misal:

Bir araba aldınız ve yakıta ihtiyacı var.

resim açıklamasını buraya girin

Otomobil modeliniz XYZtürden ABC, yani somut bir otomobil, belirli bir otomobil örneği. Araba gerçek bir nesne değildir. Aslında, belirli bir nesne yaratmak için soyut bir standartlar (nitelikler) setidir. Kısacası, Araba soyut bir sınıftır , "kendi içinde daha kapsamlı ya da daha genel bir şeyin temel niteliklerini yoğunlaştıran bir şeydir" .

Araba manuel spesifikasyonuna uyan tek yakıt, araba tankını doldurmak için kullanılmalıdır. Gerçekte, herhangi bir yakıt koymanızı kısıtlayacak bir şey yoktur, ancak motor sadece belirtilen yakıtla düzgün çalışacaktır, bu nedenle gereksinimlerini takip etmek daha iyidir. Gereklilikler, aynı türden diğer otomobiller gibi ABCstandart bir yakıt setini kabul ettiğini söylüyor .

Nesneye Dayalı bir bakış açısına göre, tür için yakıt ABCsınıf olarak ilan edilmemelidir, çünkü orada belirli bir araba türü için somut yakıt yoktur. Aracınız soyut bir sınıf Yakıt veya VehicularFuel kabul edebilse de, mevcut araç yakıtınızın sadece bir kısmının spesifikasyona uyduğunu, araç kılavuzunuzdaki gereksinimleri karşıladığını hatırlamanız gerekir. Kısacası, onlar uygulamalıdır arayüzü ABCGenreFuel , "... etkili bir şekilde koordine etmek ayrı ve bazen uyumsuz elemanları tanır" .

ek

Buna ek olarak, (daha önce bahsedilen aynı siteden) sınıf teriminin anlamını aklınızda bulundurmanız gerektiğini düşünüyorum:

Sınıf:

Ortak nitelikler, özellikler, nitelikler veya özellikler nedeniyle grup oluşturduğu düşünülen bir dizi kişi veya şey; tür;

Bu şekilde, bir sınıf (veya soyut sınıf) yalnızca ortak nitelikleri (arayüz gibi) değil, ortak niteliklere sahip bir grup grubu temsil etmelidir. Bir arayüzün bir türü temsil etmesi gerekmez. Ortak nitelikleri temsil etmelidir. Bu şekilde, bence sınıflar ve soyut sınıflar, bir insan Memeli gibi, yönlerini sık sık değiştirmemesi gereken şeyleri temsil etmek için kullanılabilir, çünkü bazı türleri temsil eder. Çeşitler kendilerini bu kadar sık ​​değiştirmemelidir.


1
çok fazla kabartmak, insanlara zaten olduğundan daha kafa karıştırıcı gelme.
ganjeii

5

Kodlama Perspektifinden

Abstract Sınıfının yalnızca soyut yöntemleri varsa, bir Arayüz bir Soyut Sınıfın yerini alabilir. Aksi takdirde Abstract sınıfını arayüz olarak değiştirmek, Miras'ın sağladığı kod yeniden kullanılabilirliğini kaybedeceğiniz anlamına gelir.

Tasarım Açısından

Bu bir "Sınıf" ilişkisidir ve bir altkümeye ya da tüm işlevlere ihtiyacınız varsa bunu Soyut Sınıf olarak saklayın. "Yapması Gerekenler" ilişkisiyse Arayüz olarak saklayın.

Neye ihtiyacınız olduğuna karar verin: sadece politika uygulaması veya kodun yeniden kullanılabilirliği VE politikası.


3

Diğer birkaç farklılık:

Soyut sınıflar statik yöntemlere, özelliklere, alanlara vb. Sahip olabilir ve operatörler, arayüzler olamaz. Cast operatörü soyut sınıfa / sınıftan döküm yapılmasına izin verir ancak arayüzden / arayüze döküm yapılmasına izin vermez.

Öyle ki, soyut sınıfı, asla uygulanmadıysa bile (statik üyeleri aracılığıyla) kendi başına kullanabilirsiniz ve arayüzü hiçbir şekilde kendi başına kullanamazsınız.


Java, arabirim üye değişkeni olabilir ama varsayılan olarak genel statik haline .. yani arabirim statik alanları olabilir
Jitendra Vispute

Evet arayüzünde statik alanlar olabilir. AMA arabiriminin statik yöntemleri olamaz.
Bir Öğrenci
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.