“Bir yöntem değişiklik yapılmadan yeniden kullanılırsa, yöntemi bir temel sınıfa koyun, başka bir arabirim oluşturun” iyi bir kural mıdır?


10

Bir meslektaşım, bir temel sınıf veya bir arayüz oluşturmak arasında seçim yapmak için bir kural belirledi.

Diyor:

Uygulamak üzere olduğunuz her yeni yöntemi düşünün. Her biri için şunu düşünün: Bu yöntem , herhangi bir değişiklik yapılmaksızın, tam olarak bu formda birden fazla sınıf tarafından uygulanacak mı? Cevap "evet" ise, bir temel sınıf oluşturun. Diğer her durumda bir arayüz oluşturun.

Örneğin:

Sınıfları düşünün catve dogsınıf uzanır, mammalve tek bir yöntem vardır pet(). Daha sonra alligator, hiçbir şeyi genişletmeyen ve tek bir yöntemi olan sınıfı ekliyoruz slither().

Şimdi, eat()hepsine bir yöntem eklemek istiyoruz .

Uygulanması halinde eat()yöntemi için tam olarak aynı olacaktır cat, dogve alligatorbiz bir temel sınıf (diyelim diyelim ki, oluşturmalıdır animalhangi uygular bu yöntemi).

Ancak, uygulanması alligatoren ufak bir şekilde farklılık gösteriyorsa, bir IEatarayüz oluşturmalı ve onu yapmalı mammalve alligatoruygulamalıyız.

Bu yöntemin tüm vakaları kapsadığı konusunda ısrar ediyor, ancak bana göre aşırı basitleştirme gibi görünüyor.

Bu genel kurallara uymaya değer mi?


27
alligator'nin uygulanması, eatelbette, kabul ettiği catve dogparametre olarak farklı olduğu yönündedir.
sbichenko

1
Uygulamaları paylaşmak için soyut bir temel sınıf kullanmak istediğiniz, ancak doğru genişletilebilirlik için arabirimler kullanmanız gerektiğinde, bunun yerine genellikle özellikleri kullanabilirsiniz . Yani, diliniz bunu destekliyorsa.
amon

2
Kendinizi bir köşeye boyadığınızda, kapıya en yakın olanda olmak en iyisidir.
JeffO

10
İnsanların yaptığı en büyük hata, arayüzlerin sadece boş soyut sınıflar olduğuna inanmaktır. Arayüz, bir programcının "Bu sözleşmeyi izlediği sürece bana ne verdiğiniz umurumda değil" demesinin bir yoludur. Daha sonra kodun yeniden kullanımı (ideal olarak) kompozisyon yoluyla gerçekleştirilmelidir. İş arkadaşınız yanlış.
riwalk

2
Bir CS uzmanı üst sınıfların olması gerektiğini is ave arayüzlerin acts likeya da olduğunu öğretti is. Yani bir köpek is amemelisi ve acts likebir yiyen. Bu bize memelinin bir sınıf ve yiyicinin bir arayüz olması gerektiğini söylerdi. Her zaman çok yardımcı bir rehber olmuştur. Sidenote: bir örnek isolacağını The cake is eatableya The book is writable.
MirroredFate

Yanıtlar:


13

Bunun iyi bir kural olduğunu düşünmüyorum. Kodun yeniden kullanımı konusunda endişeleriniz varsa, PetEatingBehaviorkediler ve köpekler için yeme işlevlerini tanımlamak olan bir rol uygulayabilirsiniz . Sonra IEatbirlikte yeniden kodlama yapabilirsiniz .

Bugünlerde miras kullanmak için gittikçe daha az neden görüyorum. Büyük bir avantaj, kullanım kolaylığıdır. Bir GUI çerçevesi alın. Bunun için bir API tasarlamanın popüler bir yolu, büyük bir temel sınıfı ortaya çıkarmak ve kullanıcının hangi yöntemleri geçersiz kılabileceğini belgelemektir. Temel sınıf tarafından "varsayılan" bir uygulama verildiğinden, uygulamamızın yönetmesi gereken diğer tüm karmaşık şeyleri göz ardı edebiliriz. Ancak yine de, gerektiğinde doğru yöntemi yeniden uygulayarak işleri özelleştirebiliriz.

API'niz için arayüze bağlı kalırsanız, kullanıcılarınızın basit örneklerin çalışması için genellikle daha fazla işi vardır. Ancak arayüzlere sahip API IEat, Mammaltemel sınıftan daha az bilgi içeren basit bir nedenden ötürü genellikle daha az bağlanır ve bakımı daha kolaydır . Böylece tüketiciler daha zayıf bir sözleşmeye bağlı olacak, daha fazla yeniden düzenleme fırsatı kazanacaksınız.

Rich Hickey'den alıntı yapmak için: Basit! = Kolay


Temel bir PetEatingBehavioruygulama örneği verebilir misiniz ?
sbichenko

1
@ exizt İlk olarak, isimleri seçmekte kötüyüm. Yani PetEatingBehaviorbüyük ihtimalle yanlış biridir. Sana bir uygulama veremem çünkü bu sadece oyuncak bir örnek. Ancak yeniden düzenleme adımlarını tanımlayabilirim: eatyöntemi (diş örneği, mide örneği, vb.) Tanımlamak için kediler / köpekler tarafından kullanılan tüm bilgileri alan bir yapıcıya sahiptir . Sadece eatyöntemlerinde kullanılan kediler ve köpekler için ortak olan kodu içerir . Bir PetEatingBehaviorüye oluşturmanız ve çağrıları dog.eat/cat.eat adresine iletmeniz yeterlidir.
Simon Bergot

Bu OP birçok miras uzak yönlendirmek için tek cevap olduğuna inanamıyorum :( Miras kod yeniden kullanım için değil!
Danny Tuppeny

1
@DannyTuppeny Neden olmasın?
sbichenko

4
@exizt Bir sınıftan miras almak büyük bir sorun; birçok dilde sadece birine sahip olabileceğiniz bir şeye (muhtemelen kalıcı) bağımlılık alıyorsunuz. Kodun yeniden kullanımı, yalnızca bu temel sınıfı kullanmak için oldukça önemsiz bir şeydir. Ya bunları başka bir sınıfla paylaşmak istediğiniz yöntemlerle sonuçlandırırsanız, ancak diğer yöntemleri yeniden kullandığından (veya hatta polimorfik olarak kullanılan "gerçek" hiyerarşinin bir parçası olduğu için zaten bir temel sınıf varsa (?)) Ne olur? ClassA bir tür ClassB olduğunda (örn. Bir Araç Araçtan miras alır) miras alın, bazı iç uygulama ayrıntılarını paylaştığında değil :-)
Danny Tuppeny

11

Bu genel kurallara uymaya değer mi?

Bu iyi bir kural, ama onu ihlal ettiğim birkaç yer biliyorum.

Adil olmak gerekirse, (soyut) temel sınıfları akranlarımdan çok daha fazla kullanıyorum. Bunu savunma amaçlı programlama olarak yapıyorum.

Bana göre (birçok dilde), soyut bir temel sınıf yalnızca bir temel sınıf olabileceğine dair temel kısıtlamayı ekler. Bir arabirim yerine bir temel sınıf kullanmayı seçerek, "bu sınıfın (ve herhangi bir mirasçı) temel işlevidir ve willy-nilly'nin diğer işlevlerle karıştırılması uygun değildir" diyorsunuz. Arayüzler tam tersidir: "Bu, bir nesnenin bir özelliği, ille de temel sorumluluğu değil".

Bu tür tasarım seçenekleri, uygulayıcılarınıza kodunuzu nasıl kullanmaları gerektiği konusunda örtülü kılavuzlar oluşturur ve uzantılarını kullanarak kodlarını yazar. Kod temeli üzerindeki daha büyük etkileri nedeniyle, tasarım kararını verirken bunları daha güçlü bir şekilde dikkate almaya eğilimliyim.


1
Bu cevabı 3 yıl sonra tekrar okuduğumda, bunun harika bir nokta olduğunu düşünüyorum: Bir arabirim yerine temel bir sınıf kullanmayı seçerek, "bu sınıfın (ve herhangi bir mirasçı) temel işlevselliği ve willy-nilly ile diğer işlevsellik karıştırmak için uygun değil "
sbichenko

9

Arkadaşınızın basitleştirilmesindeki sorun, bir yöntemin değişmesi gerekip gerekmediğinin belirlenmesinin son derece zor olmasıdır. Üst sınıfların ve arayüzlerin arkasındaki zihniyete hitap eden bir kural kullanmak daha iyidir.

İşlevselliğin ne olduğunu düşündüğünüze bakarak ne yapmanız gerektiğini bulmak yerine, oluşturmaya çalıştığınız hiyerarşiye bakın.

Bir profesörüm farkı nasıl öğretti:

Üst sınıflar is ave arayüzler acts likeveya olmalıdır is. Yani bir köpek is amemelisi ve acts likebir yiyen. Bu bize memelinin bir sınıf ve yiyicinin bir arayüz olması gerektiğini söylerdi. Bir örnek isolacağını The cake is eatableveya The book is writable(her iki yapım eatableve writablearayüzler).

Bunun gibi bir metodoloji kullanmak oldukça basit ve kolaydır ve kodun ne yapacağını düşündüğünüzden ziyade yapı ve kavramları kodlamanıza neden olur. Bu, bakımı kolaylaştırır, kodu daha okunabilir hale getirir ve tasarımın oluşturulmasını kolaylaştırır.

Kodun ne söyleyebileceğinden bağımsız olarak, böyle bir yöntem kullanırsanız, bundan beş yıl sonra geri gelebilir ve adımlarınızı takip etmek ve programınızın nasıl tasarlandığını ve nasıl etkileştiğini kolayca anlamak için aynı yöntemi kullanabilirsiniz.

Sadece iki sentim.


6

Exizt talebi üzerine, yorumumu daha uzun bir cevaba genişletiyorum.

İnsanların yaptığı en büyük hata, arayüzlerin sadece boş soyut sınıflar olduğuna inanmaktır. Arayüz, bir programcının "Bu sözleşmeyi izlediği sürece bana ne verdiğiniz umurumda değil" demesinin bir yoludur.

.NET kütüphanesi harika bir örnek. Örneğin, kabul eden bir işlev yazdığınızda IEnumerable<T>, söylediğiniz şey " Verilerinizi nasıl sakladığınız umurumda değil . Sadece bir foreachdöngü kullanabileceğimi bilmek istiyorum .

Bu, bazı çok esnek kodlara yol açar. Aniden entegre olabilmek için tek yapmanız gereken mevcut arayüzlerin kurallarına göre oynamak. Arayüzü uygulamak zor veya kafa karıştırıcıysa, belki de yuvarlak bir delikte kare bir saplamaya çalıştığınıza dair bir ipucu olabilir.

Ama sonra soru ortaya çıkıyor: "Kodun yeniden kullanımı ne olacak? CS profesörlerim bana mirasın tüm kod yeniden kullanım sorunlarına çözüm olduğunu ve mirasın bir kez yazmanıza ve her yere kullanmanıza izin verdiğini ve yetimleri kurtarma sürecinde menenjitin iyileşeceğini söyledi. yükselen denizlerden ve artık gözyaşı dökülmeyecekti vb. vb. "

"Kod yeniden kullanımı" kelimelerinin sesini sevdiğiniz için miras kullanmak oldukça kötü bir fikirdir. Google tarafından kod stil kılavuzu oldukça kısaca bu noktayı yapar:

Kompozisyon genellikle kalıtımdan daha uygundur. ... [B] bir alt sınıfı uygulayan kod, taban ve alt sınıf arasında yayıldığından, bir uygulamayı anlamak daha zor olabilir. Alt sınıf, sanal olmayan işlevleri geçersiz kılamaz, bu nedenle alt sınıf uygulamayı değiştiremez.

Neden mirasın her zaman cevap olmadığını göstermek için, MySpecialFileWriter † adlı bir sınıf kullanacağım. Mirasın tüm sorunların çözümü olduğuna körü körüne inanan bir kişi FileStream, FileStreamkodunu çoğaltmak için miras almayı denemeniz gerektiğini savunur . Akıllı insanlar bunun aptal olduğunu bilir. FileStreamSınıfınızda bir nesne (yerel veya üye değişken olarak) olmalı ve işlevselliğini kullanmalısınız.

FileStreamÖrnek yapmacık görünebilir, ama değil. Her ikisi de aynı arabirimi aynı şekilde uygulayan iki sınıfınız varsa, çoğaltılan her işlemi kapsayan üçüncü bir sınıfınız olmalıdır. Amacınız, legolar gibi bir araya getirilebilecek, tekrar kullanılabilir bloklar olan sınıflar yazmak olmalıdır.

Bu kalıtımdan kaçınılması gerektiği anlamına gelmez. Dikkate alınması gereken birçok nokta vardır ve bunların çoğu "Kompozisyon ve Miras" sorusunun araştırılmasıyla ele alınacaktır. Kendi Stack Overflow'umuzun bu konuda birkaç iyi cevabı var.

Günün sonunda, iş arkadaşınızın duyguları bilinçli bir karar vermek için gerekli derinlik veya anlayıştan yoksundur. Konuyu araştırın ve kendiniz anlayın.

† Kalıtım örneklerini verirken, herkes hayvanları kullanır. Bu işe yaramaz. 11 yıllık gelişimde, asla bir sınıf yazmadım Cat, bu yüzden onu örnek olarak kullanmayacağım.


Yani, sizi doğru anlarsam, bağımlılık enjeksiyonu kalıtımla aynı kod yeniden kullanım özelliklerini sağlar. Peki o zaman miras için ne kullanırsınız? Bir kullanım örneği sağlar mısınız? (Ben gerçekten bir ile takdir FileStream)
sbichenko

1
@ exizt, hayır aynı kod yeniden kullanım özellikleri sağlamaz. Uygulamaları daha iyi içerdiği için daha iyi kod yeniden kullanım özellikleri sağlar (birçok durumda). Sınıflar, örtük olarak yetenek kazanmak ve mevcut işlevleri aşırı yükleyerek işlevselliğin yarısını tamamen değiştirmek yerine, nesneleri ve genel API'leri aracılığıyla açıkça etkileşime girer.
riwalk

4

Örnekler, özellikle arabalar veya hayvanlar hakkında değil, nadiren bir noktaya işaret eder. Bir hayvanın yemek yeme şekli (ya da yiyecek işleme) gerçekten mirasına bağlı değildir, tüm hayvanlara uygulanacak tek bir yemek şekli yoktur. Bu daha çok fiziksel yeteneklerine bağlıdır (yani girdi, işleme ve çıktı yolları). Memeliler etobur, otobur veya omnivor olabilirken, kuşlar, memeliler ve balıklar böcek yiyebilir. Bu davranış belirli kalıplarla yakalanabilir.

Bu durumda, şöyle davranışı soyutlayarak daha iyi durumdasınız:

public interface IFoodEater
{
    void Eat(IFood food);
}

public class Animal : IFoodEater
{
    private IFoodProcessor _foodProcessor;
    public Animal(IFoodProcessor foodProcessor)
    {
        _foodProcessor = foodProcessor;
    }

    public void Eat(IFood food)
    {
        _foodProcessor.Process(food);
    }
}

Veya FoodProcessoruyumlu hayvanları beslemeye çalışan bir ziyaretçi kalıbı uygulayın ( ICarnivore : IFoodEater, MeatProcessingVisitor). Canlı hayvanlar düşüncesi, sindirim parçalarını söküp genel bir parça ile değiştirmeyi düşünmenizi engelleyebilir, ancak onlara gerçekten bir iyilik yapıyorsunuz.

Bu, hayvanınızı temel bir sınıf haline getirecek ve daha da iyisi, yeni bir yiyecek türü ve uygun bir işlemci eklerken bir daha asla değiştirmek zorunda kalmayacağınız, böylece bu belirli hayvan sınıfını yapan şeylere odaklanabilirsiniz. çok benzersiz üzerinde çalışıyor.

Yani evet, temel sınıfların yerleri var, başparmak kuralı geçerlidir (genellikle, her zaman değil, başparmak kuralı olduğu için), ancak izole edebileceğiniz davranışı aramaya devam edin.


1
IFoodEater biraz gereksizdir. Başka ne yiyebilirsin? Evet, örnek olarak hayvanlar korkunç bir şey.
Euphoric

1
Etçil bitkiler ne olacak? :) Ciddi olarak, bu durumda arayüzleri kullanmamanın önemli bir sorunu, Hayvanlarla yeme kavramını sıkı bir şekilde bağlamış olmanız ve Animal base sınıfının uygun olmadığı yeni soyutlamaları tanıtmak için çok daha fazla çalışmadır.
Julia Hayward

1
Burada "yemek" in yanlış bir fikir olduğuna inanıyorum: daha soyut. Bir IConsumerarayüze ne dersiniz ? Etçiller et tüketebilir, otoburlar bitkileri tüketir ve bitkiler güneş ışığı ve su tüketir.

2

Arayüz gerçekten bir sözleşmedir. Hiçbir işlevsellik yok. Uygulamak uygulayıcıya bağlıdır. Sözleşmenin uygulanması gerektiğinden başka seçenek yoktur.

Soyut sınıflar uygulayıcılara seçenekler sunar. Herkesin uygulaması gereken bir yöntem seçebilir, temel işlevselliğe sahip bir yöntemi geçersiz kılabilir veya tüm mirasçıların kullanabileceği bazı temel işlevler sağlayabilir.

Örneğin:

public abstract class Person
    {
        /// <summary>
        /// Inheritors must implement a hello
        /// </summary>
        /// <returns>Hello</returns>
        public abstract string SayHello();
        /// <summary>
        /// Inheritors can use base functionality, or override
        /// </summary>
        /// <returns></returns>
        public virtual string SayGoodBye()
        {
            return "Good Bye";
        }
        /// <summary>
        /// Base Functionality that is inherited 
        /// </summary>
        public void DoSomething()
        {
            //Do Something Here
        }
    }

Başparmak kuralınızın bir temel sınıf tarafından da ele alınabileceğini söyleyebilirim. Özellikle, birçok memeli muhtemelen aynı şeyi "yediğinden" bir temel sınıf kullanmak bir arayüzden daha iyi olabilir, çünkü çoğu mirasçının kullanabileceği ve daha sonra istisnai durumlar geçersiz kılabilen sanal bir yemek yöntemi uygulayabilir.

Şimdi "yeme" nin tanımı hayvandan hayvana büyük ölçüde değişiyorsa, o zaman belki de arayüz daha iyi olacaktır. Bu bazen gri bir alandır ve bireysel duruma bağlıdır.


1

Hayır.

Arayüzler yöntemlerin nasıl uygulandığı ile ilgilidir. Arayüzü ne zaman kullanacağınıza dair kararınızı yöntemlerin nasıl uygulanacağına dayandırıyorsanız, yanlış bir şey yapıyorsunuz demektir.

Benim için arayüz ve temel sınıf arasındaki fark, gereksinimlerin nerede olduğu ile ilgilidir. Bir kod parçası, belirli bir API ve bu API'dan kaynaklanan zımni davranışa sahip bir sınıf gerektirdiğinde arayüz oluşturursunuz. Gerçekten çağıracak kod olmadan bir arabirim oluşturamazsınız.

Diğer tarafta, temel sınıflar genellikle kodu yeniden kullanmanın bir yolu olarak ifade edilir, bu nedenle bu temel sınıfı çağıracak ve yalnızca bu temel sınıfın parçası olduğu nesnelerin aranmasını dikkate alacak kodla nadiren uğraşırsınız.


Neden tekrar uygulamasını Bekle eat()içinde her hayvandan? Uygulayabiliriz, mammaldeğil mi? Gerçi gereksinimler hakkındaki fikrinizi anlıyorum.
sbichenko

@exizt: Üzgünüm, sorunuzu yanlış okudum.
Euphoric

1

Bu gerçekten iyi bir kural değil çünkü farklı uygulamalar istiyorsanız her zaman soyut bir yöntemle soyut bir temel sınıfınız olabilir. Her mirasçının bu yönteme sahip olduğu garanti edilir, ancak her biri kendi uygulamasını tanımlar. Teknik olarak, bir dizi soyut yöntemden başka bir şey olmayan soyut bir sınıfa sahip olabilirsiniz ve temel olarak bir arayüzle aynı olurdu.

Temel sınıflar, birkaç sınıfta kullanılabilecek bazı durum veya davranışların gerçek bir uygulamasını istediğinizde kullanışlıdır. Kendinizi aynı alanlara ve aynı uygulamalara sahip yöntemlere sahip birkaç sınıfla bulursanız, bunu bir temel sınıfa yeniden aktarabilirsiniz. Sadece nasıl miras aldığınıza dikkat etmelisiniz. Temel sınıftaki mevcut her alan veya yöntem, özellikle temel sınıf olarak kullanıldığında, mirasçıda anlamlı olmalıdır.

Arabirimler, bir grup sınıfla aynı şekilde etkileşim kurmanız gerektiğinde yararlıdır, ancak gerçek uygulamalarını tahmin edemez veya umursamazsınız. Örneğin, Koleksiyon arayüzü gibi bir şeyi ele alalım. Rab sadece bir insanın bir koleksiyon koleksiyonu uygulamaya karar verebileceği sayısız yolu bilir. Bağlantılı liste? Dizi listesi? Yığın? Kuyruk? Bu SearchAndReplace yöntemi umursamıyor, sadece Add, Remove ve GetEnumerator diyebileceği bir şey geçirilmesi gerekiyor.


1

Başkalarının ne söyleyeceğini görmek için bu sorunun cevabını kendim izliyorum, ama bunu düşünmeye meyilli olduğum üç şey söyleyeceğim:

  1. İnsanlar arayüzlere çok fazla inanç ve sınıflara çok az inanç koydular. Arayüzler temelde çok sulandırılmış taban sınıflarıdır ve hafif bir şey kullanıldığında aşırı kazan plakası kodu gibi şeylere yol açabilir.

  2. Bir yöntemi geçersiz kılmak, super.method()onu çağırmak ve vücudunun geri kalanının sadece temel sınıfa müdahale etmeyen şeyler yapmasına izin vermekle ilgili yanlış bir şey yoktur . Bu Liskov İkame İlkesini ihlal etmez .

  3. Genel bir kural olarak, bir şey genellikle en iyi uygulama olsa bile, yazılım mühendisliğinde bu katı ve dogmatik olmak kötü bir fikirdir.

Bu yüzden söylenenleri bir tuz tanesi ile alırdım.


5
People put way too much faith into interfaces, and too little faith into classes.Komik. Tam tersinin doğru olduğunu düşünmeye meyilliyim.
Simon Bergot

1
"Bu Liskov İkame İlkesini ihlal etmiyor." Ancak LSP'nin ihlali haline gelmek son derece yakındır. Üzülmektense tedbirli olmak iyidir.
Euphoric

1

Buna karşı dilsel ve anlamsal bir yaklaşım benimsemek istiyorum. Bir arayüz orada değil DRY. Onu uygulayan soyut bir sınıfa sahip olmanın yanı sıra merkezileşme için bir mekanizma olarak da kullanılabilmesine rağmen, DRY için değildir.

Arayüz bir sözleşmedir.

IAnimalarayüz, timsah, kedi, köpek ve bir hayvan kavramı arasındaki ya hep ya hiç sözleşmesidir. Esas olarak "hayvan olmak istiyorsanız, ya tüm bu özelliklere ve özelliklere sahip olmalısınız ya da artık bir hayvan değilsiniz" dir.

Diğer taraftaki miras yeniden kullanım için bir mekanizmadır. Bu durumda, iyi bir anlamsal akıl yürütmenin olması, hangi yöntemin nereye gideceğine karar vermenize yardımcı olabilir. Örneğin, tüm hayvanlar aynı şekilde uyuyabilir ve aynı şekilde uyuyabilirken, bunun için bir temel sınıf kullanmayacağım. Sleep()Metodu önce IAnimalarayüze hayvan olmanın ne anlama geldiğine vurgu (anlamsal) olarak koydum , sonra kendimi tekrarlamamak için bir programlama tekniği olarak kedi, köpek ve timsah için temel bir soyut sınıf kullanıyorum.


0

Bunun en iyi kural olduğuna emin değilim. abstractTemel sınıfa bir yöntem koyabilir ve her sınıfın bunu uygulamasını sağlayabilirsiniz. Her zamandan berimammal yemek zorunda olduğu için bunu yapmak mantıklı olacaktır. Sonra her biri mammalkendi eatyöntemini kullanabilir . Genellikle yalnızca nesneler arasındaki iletişim için arabirimleri veya bir sınıfı bir şey olarak işaretlemek için bir marker olarak kullanırım. Bence aşırı arayüzler özensiz kod yapar.

Ayrıca @Panzercrisis ile aynı fikirdeyim, genel bir kural olması gerekir. Taşla yazılması gereken bir şey değil. Kuşkusuz, sadece çalışmadığı zamanlar olacaktır.


-1

Arabirimler türlerdir. Hiçbir uygulama sağlamazlar. Bu tür işlemleri yapmak için sözleşmeyi basitçe tanımlarlar. Bu sözleşme, arayüzü uygulayan herhangi bir sınıf tarafından karşılanmalıdır.

Arayüzlerin ve soyut / temel sınıfların kullanımı tasarım gerekliliklerine göre belirlenmelidir.

Tek bir sınıf arabirim gerektirmez.

İki sınıf bir işlev içinde değiştirilebilirse, ortak bir arabirim uygulamalıdırlar. Aynı şekilde uygulanan herhangi bir işlevsellik daha sonra arabirimi uygulayan soyut bir sınıfa dönüştürülebilir. Ayırt edici işlevsellik yoksa, arabirim bu noktada gereksiz kabul edilebilir. Peki iki sınıf arasındaki fark nedir?

Daha fazla işlevsellik eklendikçe ve bir hiyerarşi genişledikçe soyut sınıfları tür olarak kullanmak genellikle dağınıktır.

Kompozisyonu miras yerine tercih edin - tüm bunlar ortadan kalkar.

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.