Tektonların, soyut sınıfların ve arayüzlerin rolleri nelerdir?


13

C ++ 'da OOP okuyorum ve bu 3 kavramın tanımlarının farkında olmama rağmen, onu ne zaman veya nasıl kullanacağımı gerçekten anlayamıyorum.

Örnek olarak bu sınıfı kullanalım:

class Person{
    private:
             string name;
             int age;
    public:
             Person(string p1, int p2){this->name=p1; this->age=p2;}
             ~Person(){}

             void set_name (string parameter){this->name=parameter;}                 
             void set_age (int parameter){this->age=parameter;}

             string get_name (){return this->name;}
             int get_age (){return this->age;}

             };

1. Singleton

Sınıfın yalnızca bir nesneye sahip olması kısıtlaması nasıl çalışır?

CAN Eğer olurdu bir sınıf tasarım SADECE 2 örneklerini? Ya da belki 3?

ZAMAN / gerekli tavsiye a tek kullanıyor? İyi bir uygulama mı?

2. Soyut Sınıf

Bildiğim kadarıyla, sadece bir saf sanal işlev varsa, sınıf soyutlaşır. Yani,

virtual void print ()=0;

yapardı değil mi?

NEDEN nesnesi gerekli olmayan bir sınıfa ihtiyacınız var?

3.Interface

Bir arabirim, tüm yöntemlerin saf sanal işlevler olduğu soyut bir sınıfsa, o zaman

NE 2 tanesi arasındaki temel fark nedir?

Şimdiden teşekkürler!


2
Singleton tartışmalı, çeşitli görüşler almak için bu sitede bir arama yapın.
Winston Ewert

2
Soyut sınıfların dilin bir parçası olmasına rağmen, ne tektonların ne de arayüzlerin olmadığını da belirtmek gerekir. Bunlar insanların uyguladığı kalıplardır. Özellikle Singleton, iş yapmak için biraz akıllıca saldırı gerektiren bir şeydir. (Tabii ki sadece kongre ile bir singleton oluşturabilirsiniz.)
Robot

1
Birer birer lütfen.
JeffO

Yanıtlar:


17

1. Singleton

Örneklerin sayısını kısıtlarsınız çünkü kurucu özel olacaktır, yani yalnızca statik yöntemler o sınıfın örneklerini oluşturabilir (aslında bunu gerçekleştirmek için başka kirli numaralar vardır, ancak taşınmayalım).

Sadece 2 veya 3 örneği olacak bir sınıf oluşturmak mükemmel bir şekilde mümkündür. Tüm sistemde bu sınıfın yalnızca bir örneğine sahip olmanın gerekliliğini hissettiğinizde singleton kullanıyor olmalısınız. Bu genellikle 'yönetici' davranışı olan sınıflarda olur.

Singletons hakkında daha fazla bilgi edinmek istiyorsanız Wikipedia'da başlayabilir ve özellikle bu yazıda C ++ için başlayabilirsiniz .

Bu model hakkında kesinlikle iyi ve kötü şeyler var ama bu tartışma başka bir yere ait.

2. Soyut Sınıflar

Evet bu doğru. Yalnızca tek bir sanal yöntem sınıfı soyut olarak işaretler.

En iyi sınıfların gerçekten somutlaştırılmaması gereken daha büyük bir sınıf hiyerarşisine sahip olduğunuzda bu tür sınıfları kullanacaksınız.

Diyelim ki bir Memeli sınıfı tanımlıyorsunuz ve sonra onu Köpek ve Kedi'ye miras alıyorsunuz. Bunu düşünürseniz, gerçekte ne tür bir Memeli olduğunu bilmeniz gerektiğinden, saf bir Memeli örneğine sahip olmanızın bir anlamı yoktur.

Potansiyel olarak MakeSound () adında, kalıtsal sınıflarda anlamlı olacak bir yöntem vardır, ancak tüm memelilerin yapabileceği ortak bir ses yoktur (Bu sadece memelinin sesleri için bir dava yapmaya çalışmayan bir örnektir).

Yani bu, Memelinin soyut bir sınıf olması gerektiği anlamına gelir, çünkü tüm memelilere bazı ortak davranışlar uygular, ancak gerçekte somutlaştırılması gerekmez. Soyut sınıfların arkasındaki temel kavram budur, ancak öğrenmeniz gereken kesinlikle daha fazlası vardır.

3. Arayüzler

Java veya C # ile aynı anlamda C ++ 'da saf arayüzler yoktur. Bir tane oluşturmanın tek yolu, bir arayüzden istediğiniz davranışların çoğunu taklit eden saf bir soyut sınıfa sahip olmaktır.

Temel olarak aradığınız davranış, temeldeki uygulamaya dikkat etmeden diğer nesnelerin etkileşime girebileceği bir sözleşme tanımlamaktır. Bir sınıfı tamamen soyutlaştırdığınızda, bu, tüm uygulamanın başka bir yere ait olduğu anlamına gelir, bu nedenle o sınıfın amacı yalnızca tanımladığı sözleşme ile ilgilidir. Bu, OO'da çok güçlü bir kavram ve kesinlikle daha fazla bakmalısınız.

Daha iyi bir fikre sahip olmak için MSDN'deki C # için arayüz özellikleri hakkında bilgi edinebilirsiniz:

http://msdn.microsoft.com/en-us/library/ms173156.aspx

C ++ saf bir soyut sınıfa sahip olarak aynı tür davranışlar sağlayacaktır.


2
Saf bir soyut temel sınıf size bir arayüzün yaptığı her şeyi verir. Java (ve C #) 'da arayüzler vardır, çünkü dil tasarımcıları çoklu kalıtımı (yarattığı baş ağrıları nedeniyle) önlemek istediler, ancak sorunlu olmayan çoklu kalıtımın çok yaygın bir kullanımını fark ettiler.
Robot Gort

@StevenBurnap: Ancak sorunun bağlamı olan C ++ ile değil.
DeadMG

3
C ++ ve arayüzleri soruyor. "Arayüz" C ++ 'nın bir dil özelliği değildir, ancak insanlar kesinlikle C ++' da soyut temel sınıfları kullanarak tam olarak Java arayüzleri gibi çalışan arayüzler oluştururlar. Bunu Java var olmadan önce yaptılar.
Robot Gort


1
Aynısı Singletons için de geçerlidir. C ++ 'da, her ikisi de dil özellikleri değil tasarım kalıplarıdır. Bu, insanların C ++ arayüzleri ve ne için oldukları hakkında konuşmadıkları anlamına gelmez. "Arayüz" kavramı, her ikisi de orijinal olarak saf C'de kullanılmak üzere geliştirilmiş olan Corba ve COM gibi bileşen sistemlerinden ortaya çıkmıştır. C ++ 'da, arayüzler genellikle tüm yöntemlerin sanal olduğu soyut temel sınıflarla uygulanır. Bunun işlevselliği, Java arayüzünün işleviyle aynıdır. Bu nedenle, Java arabirimi kavramı bilerek C ++ soyut sınıflarının bir alt kümesidir.
Robot Gort

8

Çoğu insan zaten tekil / soyut sınıfların ne olduğunu açıkladı. Umarım biraz farklı bir bakış açısı sunacağım ve bazı pratik örnekler vereceğim.

Tek Tonlar - Tüm arama kodlarının tek bir değişken örneği kullanmasını istediğinizde, herhangi bir nedenle, aşağıdaki seçenekleriniz vardır:

  • Global değişkenler - açıkçası kapsülleme yok, kodun çoğu globallere bağlı ... kötü
  • Tüm statik işlevlere sahip bir sınıf - basit küresellerden biraz daha iyi, ancak bu tasarım kararı sizi kodun küresel verilere dayandığı ve daha sonra değiştirilmesinin çok zor olabileceği bir yola doğru götürüyor. Ayrıca, sahip olduğunuz tek şey statik fonksiyonlarsa, polimorfizm gibi OO şeylerinden yararlanamazsınız.
  • Singleton - Sınıfın sadece bir örneği olmasına rağmen, sınıfın gerçek uygulamasının küresel olduğu gerçeği hakkında hiçbir şey bilmek zorunda değildir. Yani bugün bir singleton sınıfına sahip olabilirsiniz, yarın yapıcısını herkese açık hale getirebilir ve müşterilerin birden fazla kopya oluşturmasını sağlayabilirsiniz. Singleton'a başvuran çoğu istemci kodunun değişmesi gerekmeyecek ve singletonun kendisinin uygulanmasının değişmesi gerekmeyecektir. Tek değişiklik, istemci kodunun ilk etapta nasıl singleton referansı alacağıdır.

Dışarıdaki tüm kötü ve kötü seçeneklerden, eğer küresel verilere ihtiyacınız varsa, singleton önceki iki yöntemden çok daha iyi bir yaklaşımdır. Ayrıca, yarın fikrinizi değiştirirseniz ve global verilere sahip olmak yerine kontrolün tersini kullanmaya karar verirseniz seçeneklerinizi açık tutmanıza olanak tanır .

Peki nerede bir singleton kullanırsın? İşte birkaç örnek:

  • Günlüğe kaydetme - tüm işleminizin tek bir günlüğe sahip olmasını istiyorsanız, bir günlük nesnesi oluşturabilir ve her yere aktarabilirsiniz. Peki ya 100.000.000 satır eski uygulama kodunuz varsa? hepsini değiştir? Ya da sadece aşağıdakileri tanıtabilir ve istediğiniz her yerde kullanmaya başlayabilirsiniz:

    CLog::GetInstance().write( "my log message goes here" );
  • Sunucu bağlantısı önbelleği - Bu, uygulamamızda tanıtmak zorunda olduğum bir şeydi. Bizim kod tabanı, ve bir sürü vardı, ne zaman memnun sunuculara bağlanmak için kullanılır. Çoğu zaman ağda herhangi bir gecikme olmadığı sürece bu ok. Bir çözüme ihtiyacımız vardı ve 10 yıllık bir uygulamanın gerçekten masanın üstünde olmadığını yeniden tasarladık. Tek bir CServerConnectionManager yazdım. Sonra kod üzerinden arama ve sınıfımı çağırdı özdeş imza çağrısı ile CoCreateInstanceWithAuth çağrıları değiştirdi. Şimdi ilk denemeden sonra bağlantı önbelleğe alındı ​​ve geri kalan zaman "bağlantı" girişimleri anlık oldu. Bazıları singletonların kötü olduğunu söylüyor. Diyorum ki kıçımı kurtardılar.

  • Hata ayıklama için, genellikle çalışan global nesne tablosunun çok yararlı olduğunu görürüz. Takip etmek istediğimiz bazı derslerimiz var. Hepsi aynı temel sınıftan türemiştir. Örnekleme sırasında, nesne tablosunu singleton olarak adlandırırlar ve kendilerini kaydederler. Yok edildiklerinde kayıtlarını kaldırırlar. Herhangi bir makineye yürüyebilir, bir sürece ekleyebilir ve çalışan nesnelerin bir listesini oluşturabilirim. Yarım on yılı aşkın süredir üründe ve hiç 2 "küresel" nesne tablolarına ihtiyaç duyduğumuzu hiç hissetmedim.

  • Düzenli ifadelere dayanan bazı nispeten karmaşık dize ayrıştırıcı yardımcı program sınıflarımız var. Normal ifade sınıflarının eşleşmeleri gerçekleştirebilmesi için başlatılması gerekir. Başlatma biraz pahalı çünkü ayrıştırma dizesine dayalı bir FSM üretiliyor. Ancak bundan sonra, düzenli ifade sınıfına 100 iş parçacığıyla güvenli bir şekilde erişilebilir çünkü bir kez oluşturulmuş FSM hiçbir zaman değişmez. Bu ayrıştırıcı sınıfları, bu başlatmanın yalnızca bir kez gerçekleştiğinden emin olmak için dahili olarak tektonlar kullanır. Bu, performansı önemli ölçüde geliştirdi ve "kötü singletonlar" nedeniyle hiçbir zaman sorun yaratmadı.

Tüm bunları söyledikten sonra, singletonları ne zaman ve nerede kullanacağınızı aklınızda bulundurmanız gerekir. 10 kez 9'u daha iyi bir çözüm var ve elbette bunu kullanmalısınız. Bununla birlikte, singleton'un kesinlikle doğru tasarım seçimi olduğu zamanlar vardır.

Sonraki konu ... arayüzler ve soyut sınıflar. Birincisi, diğerlerinin de belirttiği gibi, arayüz soyut bir sınıftır, ancak kesinlikle HİÇBİR uygulaması olmadığını zorlayarak bunun ötesine geçer. Bazı dillerde interface anahtar sözcüğü dilin bir parçasıdır. C ++ 'da sadece soyut sınıfları kullanıyoruz. Microsoft VC ++ bunu dahili olarak bir yerde tanımlamak için bir adım attı:

typedef struct interface;

... yani yine de interface anahtar sözcüğünü kullanabilirsiniz (hatta 'gerçek' anahtar kelime olarak vurgulanacaktır), ancak asıl derleyici söz konusu olduğunda, bu sadece bir yapıdır.

Peki bunu nerede kullanırdın? Çalışan bir nesne tablosu örneğime geri dönelim. Diyelim ki temel sınıf ...

sanal geçersiz baskı () = 0;

İşte sizin soyut sınıfınız. Çalışma zamanı nesne tablosu kullanan sınıfların tümü aynı temel sınıftan türetilir. Temel sınıf, kayıt / kayıt silme için ortak kod içerir. Ancak asla kendi başına somutlaştırılamaz. Şimdi türetme sınıfları (örneğin, istekler, dinleyiciler, istemci bağlantı nesneleri ...), her biri print () uygulayacak, böylece sürece eklemek ve sormak, ne çalışıyor, her nesne kendi durumunu bildirecektir.

Soyut sınıfların / arayüzlerin örnekleri sayısızdır ve bunları tek tek kullanacağınızdan çok daha sık kullanırsınız (veya kullanmalısınız). Kısacası, temel türlerle çalışan ve gerçek uygulamaya bağlı olmayan kod yazmanıza izin verir. Bu, daha sonra çok fazla kod değiştirmek zorunda kalmadan uygulamayı değiştirmenize olanak tanır.

İşte başka bir örnek. Bir logger uygulayan bir sınıfım olduğunu varsayalım, CLog. Bu sınıf, yerel diskteki dosyaya yazar. Bu sınıfı eski 100.000 kod satırımda kullanmaya başladım. Her yerde. Birisi diyene kadar hayat güzel, hey hadi dosya yerine veritabanına yazalım. Şimdi yeni bir sınıf oluşturuyorum, buna CDbLog diyelim ve veritabanına yazıyorum. 100.000 satırdan geçip her şeyi CLog'dan CDbLog'a değiştirme zahmetini görebiliyor musunuz? Alternatif olarak:

interface ILogger {
    virtual void write( const char* format, ... ) = 0;
};

class CLog : public ILogger { ... };

class CDbLog : public ILogger { ... };

class CLogFactory {
    ILogger* GetLog();
};

Tüm kod ILogger arabirimini kullanıyor olsaydı, tüm değiştirmek zorunda CLogFactory :: GetLog () iç uygulamasıdır. Kodun geri kalanı, bir parmağımı kaldırmak zorunda kalmadan otomatik olarak çalışır.

Arayüzler ve iyi OO tasarımı hakkında daha fazla bilgi için Bob Amca'nın C # 'daki Çevik Prensipleri, Desenleri ve Uygulamaları'nı şiddetle tavsiye ederim . Kitap, soyutlamaları kullanan örneklerle doludur ve her şeyin açık bir dilini açıklar.


4

Önerilen / gerekli olan bir singleton ne zaman? İyi bir uygulama mı?

Asla. Daha da kötüsü, kurtulmak için mutlak bir orospu, bu hatayı bir kez yapmak sizi yıllarca rahatsız edebilir.

Soyut sınıflar ve arayüzler arasındaki fark kesinlikle C ++ 'da değildir. Genellikle türetilmiş sınıfın bazı davranışlarını belirtmek için arabirimlere sahipsiniz, ancak tümünü belirtmek zorunda kalmadan. Bu, kodunuzu daha esnek hale getirir, çünkü daha sınırlı spesifikasyonu karşılayan herhangi bir sınıfı değiştirebilirsiniz. Çalışma zamanı arabirimleri, çalışma zamanı soyutlamasına ihtiyacınız olduğunda kullanılır.


Arayüzler soyut sınıfların bir alt kümesidir. Arayüz, tanımlanmış yöntemi olmayan soyut bir sınıftır. (Hiç kodu olmayan soyut bir sınıf.)
Robot

1
@StevenBurnap: Belki başka bir dilde.
DeadMG

4
"Arayüz" sadece C ++ 'da bir kuraldır. Kullanıldığını gördüğümde, sadece saf sanal yöntemlere sahip ve özellikleri olmayan soyut bir sınıf. Açıkçası herhangi bir eski sınıf yazabilir ve adın önüne "I" tokat atabilirsiniz.
Robot Gort

İnsanların bu gönderiye cevap vermesini bekledim. Her seferinde bir soru. Her neyse, bilginizi paylaştığınız için çok teşekkürler. Bu topluluk zaman ayırmaya değer.
appoll

3

Singleton , belirli bir nesnenin birden fazla kopyasını istemediğinizde yararlıdır, bu sınıfın yalnızca bir örneği olmalıdır - küresel durumu koruyan, bir şekilde evresel olmayan kodlarla uğraşmak zorunda kalan nesneler için kullanılır vb.

Sabit sayıda 2 veya daha fazla örneği olan bir singleton, bir multiton , veritabanı bağlantı havuzu oluşturma vb.

Arayüz , nesneler arasındaki etkileşimi modellemeye yardımcı olan iyi tanımlanmış bir API belirtir. Bazı durumlarda, bazı ortak işlevlere sahip bir grup sınıfınız olabilir - öyleyse, uygulamalarda çoğaltmak yerine, arabirime soyut bir sınıfa dönüştüren yöntem tanımları ekleyebilirsiniz .

Tüm yöntemlerin uygulandığı soyut bir sınıf bile olabilir, ancak alt sınıflama olmadan olduğu gibi kullanılmaması gerektiğini belirtmek için soyut olarak işaretleyebilirsiniz.

Not: Arayüz ve soyut sınıf, çoklu kalıtım vb. İle C ++ dünyasında çok farklı değildir, ancak Java ve ark.


Çok güzel söyledi! +1
jmort253

3

Bunu düşünmeyi bırakırsanız, hepsi polimorfizmle ilgilidir. Ne geçtiklerine bağlı olarak bir düşünmeden daha fazlasını yapabilen bir kez bir parça kod yazabilmek istiyorsunuz.

Diyelim ki aşağıdaki Python kodu gibi bir fonksiyonumuz var:

function foo(objs):
    for obj in objs:
        obj.printToScreen()

class HappyWidget:
    def printToScreen(self):
        print "I am a happy widget"

class SadWidget:
    def printToScreen(self):
        print "I am a sad widget"

Bu işlevle ilgili iyi bir şey, bu nesneler bir "printToScreen" yöntemi uyguladığı sürece herhangi bir nesne listesini işleyebilmesidir. Mutlu widget'ların bir listesini, üzücü widget'ların bir listesini veya hatta bunların bir karışımını içeren bir listeyi aktarabilirsiniz ve foo işlevi yine de doğru olanı yapabilir.

Bir arabirim olarak bir dizi yöntem uygulanmasına (bu durumda printToScreen) ihtiyaç duyulmasına ilişkin bu tür kısıtlamadan bahsediyoruz ve tüm yöntemleri uygulayan nesnelerin arabirimi uyguladığı söyleniyor.

Python gibi dinamik, ördek tipi bir dilden bahsediyor olsaydık, temelde artık sona ererdik. Bununla birlikte, C ++ 'ın statik tip sistemi, fonksiyonumuzdaki nesnelere bir sınıf vermemizi talep eder ve sadece bu ilk sınıfın alt sınıflarıyla çalışabilir.

void foo( Printable *objs[], int n){ //Please correctme if I messed up on the type signature
    for(int i=0; i<n; i++){
        objs[i]->printToScreen();
    }
}

Bizim durumumuzda, Printable sınıfının var olmasının tek nedeni printToScreen yönteminin var olması için bir yer vermektir. PrintToScreen yöntemini uygulayan sınıflar arasında paylaşılan bir uygulama olmadığından, Printable'ı yalnızca benzer sınıfları ortak bir hiyerarşide gruplamanın bir yolu olarak kullanılan soyut bir sınıfa dönüştürmek mantıklıdır .

C ++ 'da absctract sınıfı ve arayüz kavramları biraz bulanıktır. Bunları daha iyi tanımlamak istiyorsanız, soyut sınıflar düşündüğünüz şeydir, arayüzler genellikle bir nesnenin ortaya koyduğu görünür yöntem kümesinin daha genel, çapraz dil fikri anlamına gelir. (Java gibi bazı diller, soyut bir temel sınıf gibi daha doğrudan bir şeye başvurmak için arayüz terimini kullanır)

Temel olarak, somut sınıflar nesnelerin nasıl uygulanacağını belirtirken, soyut sınıflar da kodun geri kalanıyla nasıl arayüz oluşturduklarını belirtir. İşlevlerinizi daha çok polimorf haline getirmek için, mantıklı olduğu zaman soyut süper sınıfa bir işaretçi almaya çalışmalısınız.


Singletons'a gelince, bunlar gerçekten işe yaramaz, çünkü genellikle sadece bir grup statik yöntem veya düz eski işlevlerle değiştirilebilirler. Bununla birlikte, bazen gerçekten bir tane kullanmak istemeseniz bile, sizi bir nesneyi kullanmaya zorlayan bir tür kısıtlama vardır, bu yüzden tekli pıtırtı uygundur.


BTW, bazı insanlar "arayüz" kelimesinin Java dilinde özel bir anlamı olduğunu yorumlamış olabilir. Bence şimdilik daha genel tanımlara uymak daha iyi.


1

Arayüzler

Hiç yaşamadığınız bir sorunu çözen bir aracın amacını anlamak zor. Programlamaya başladıktan sonra bir süre arayüzleri anlamadım. Ne yaptýklarýný anlayacađým, ama neden kullanmak istediđini bilmiyordum.

İşte sorun - ne yapmak istediğinizi biliyorsunuz, ancak bunu yapmak için birden fazla yolunuz var veya daha sonra nasıl yapacağınızı değiştirebilirsiniz. Clueless yöneticinin rolünü oynayabilirseniz iyi olur - bazı siparişleri havlayın ve nasıl yapıldığına dikkat etmeden istediğiniz sonuçları alın.

Küçük bir web siteniz olduğunu ve tüm kullanıcı bilgilerinizi bir csv dosyasına kaydettiğinizi varsayalım. En sofistike çözüm değil, ancak annenizin kullanıcı ayrıntılarını saklamak için yeterince iyi çalışıyor. Daha sonra siteniz yayınlanıyor ve 10.000 kullanıcınız var. Belki de uygun bir veritabanı kullanma zamanı gelmiştir.

İlk başta zeki olsaydınız, bunun geldiğini görürdünüz ve doğrudan csv'ye kaydetmek için çağrı yapmazdınız. Bunun yerine, nasıl uygulandığına bakılmaksızın ne yapmanız gerektiğini düşünürdünüz. Diyelim store()ve retrieve(). Bir yapmak Persisteriçin soyut yöntemlerle arayüzü store()ve retrieve()ve bir oluşturmak CsvPersisteraslında bu yöntemleri uygulayan alt sınıf.

Daha sonra, DbPersisterverilerin gerçek depolanmasını ve alınmasını csv sınıfınızın yaptığı işlemden tamamen farklı bir uygulama oluşturabilirsiniz .

Harika olan şey şu an tek yapmanız gereken değişim

Persister* prst = new CsvPersister();

için

Persister* prst = new DbPersister();

ve sonra işiniz bitti. Sizin çağrılarınız prst.store()ve prst.retrieve()hepsi hala çalışacaktır, onlar sadece "perde arkasında" farklı ele alınır.

Şimdi, hala cvs ve db uygulamalarını oluşturmak zorundaydınız, bu yüzden henüz patron olmanın lüksünü deneyimlemediniz. Başka birinin oluşturduğu arayüzleri kullandığınızda gerçek faydalar açıktır. Başkası oluşturmak nezaketini olsaydı CsvPersister()ve DbPersister()zaten, o zaman sadece gerekli yöntemler birini seçmek ve aramak zorunda. Diğerini daha sonra veya başka bir projede kullanmaya karar verirseniz, nasıl çalıştığını zaten biliyorsunuzdur.

C ++'mda gerçekten paslıyım, bu yüzden sadece bazı genel programlama örneklerini kullanacağım. Konteynerler, arayüzlerin hayatınızı nasıl kolaylaştırdığını gösteren harika bir örnektir.

Sen olabilir Array, LinkedList, BinaryTreevb tüm alt sınıfların Containergibi yöntemleri vardır ki insert(), find(), delete().

Bağlantılı listenin ortasına bir şey eklerken, bağlantılı listenin ne olduğunu bile bilmenize gerek yok. Sadece arayın myLinkedList->insert(4)ve sihirli bir şekilde listeyi tekrarlar ve oraya yapışır. Bağlantılı bir listenin nasıl çalıştığını bilseniz bile (gerçekten yapmanız gerekir), belirli işlevlerine bakmanız gerekmez, çünkü muhtemelen daha Containerönce farklı bir kullanımdan ne olduklarını biliyorsunuzdur .

Soyut Sınıflar

(İyi teknik arayüzleri Özet sınıflar arayüzleri oldukça benzer olan bazı yöntemleri fleshed var Acımasız taban sınıfları soyut sınıf, ama burada.

Bir oyun oluşturduğunuzu ve düşmanların oyuncunun çarpıcı mesafesine ne zaman geldiğini tespit etmeniz gerektiğini varsayalım. EnemyBir yöntemi olan bir temel sınıf oluşturabilirsiniz inRange(). Düşmanlar hakkında farklı olan birçok şey olmasına rağmen, menzillerini kontrol etmek için kullanılan yöntem tutarlıdır. Bu nedenle Enemysınıfınızda menzili kontrol etmek için etli bir yöntem olacak, ancak düşman türleri arasında benzerlik paylaşmayan diğer şeyler için saf sanal yöntemler olacak.

Bu konuda güzel bir şey, menzil algılama kodunu karıştırırsanız veya değiştirmek isterseniz, sadece bir yerde değiştirmeniz gerekir.

Tabii ki arayüzler ve soyut temel sınıflar için başka birçok neden var, ancak bunlar bunları kullanmanızın bazı nedenleri.

singletons

Onları zaman zaman kullanıyorum ve onlar tarafından hiç yakılmadım. Bu, diğer insanların deneyimlerine dayanarak hayatımı bir noktada mahvetmeyecekleri anlamına gelmez.

İşte bazı daha deneyimli ve ihtiyatlı kişilerden küresel devlet hakkında iyi bir tartışma: Küresel Devlet neden bu kadar Kötülük?


1

Hayvanlar aleminde memeliler olan çeşitli hayvanlar vardır. Burada memeli bir temel sınıftır ve ondan çeşitli hayvanlar türetilmiştir.

Hiç yürüyen bir memeli gördün mü? Evet, pek çok kez eminim - ancak her tür memeli bunlar değil mi?

Asla sadece bir memeli olan bir şey görmedin. Hepsi memeliydi.

Sınıf memelisinin çeşitli özellikleri ve grupları tanımlaması gerekir, ancak fiziksel bir varlık olarak mevcut değildir.

Dolayısıyla soyut bir temel sınıftır.

Memeliler nasıl hareket eder? Yürüyorlar, yüzüyorlar, uçuyorlar, vb.

Memeli düzeyinde bilmenin bir yolu yoktur, ancak tüm memeliler bir şekilde hareket etmelidir (örneği daha kolay hale getirmek için bunun biyolojik bir yasa olduğunu söyleyelim).

Bu nedenle MoveAround () sanal bir işlevdir, çünkü bu sınıftan türeyen her memelinin farklı şekilde uygulayabilmesi gerekir.

Bununla birlikte, her memelinin MoveAround'u tanımlaması ZORUNLUDUR çünkü tüm memelilerin hareket etmesi gerekir ve bunu memeli seviyesinde yapmak imkansızdır. Tüm çocuk sınıfları tarafından uygulanmalıdır, ancak burada temel sınıfta bir anlamı yoktur.

Bu nedenle MoveAround saf bir sanal işlevdir.

Etkinliğe izin veren ancak en üst düzeyde nasıl yapılması gerektiğini tanımlayamayan bir sınıfınız varsa, tüm işlevler saf sanaldır ve bu bir arabirimdir.
Örneğin - bir robotu kodlayacağınız ve bir savaş alanında savaşmak için bana göndereceğiniz bir oyunumuz varsa, çağrılacak fonksiyon isimlerini ve prototipleri bilmem gerekir. 'Arayüz' açık olduğu sürece onu nasıl uyguladığınız umurumda değil. Bu nedenle size katil robotunuzu yazmak için kullanacağınız bir arayüz sınıfı sağlayabilirim.

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.