Bir Sınıfı Genişleterek Yeniden Kullanma
Yapıcılarla sınıflar oluşturup yıkıcılarla temizlediniz. Kalıtım bir sonraki adımdır: bir sınıfın üyelerini başka bir sınıfa kopyalamak yerine, yeni bir sınıfın var olan bir sınıfın özelleşmiş bir sürümü olduğunu bildirir ve her şeyi otomatik olarak miras almasını sağlarsınız.
Var olan sınıf temel sınıftır (ya da üst sınıf); yeni olan ise türetilmiş sınıftır (ya da alt sınıf). Türetilmiş bir sınıf, temel sınıfın tüm verisi ve davranışıyla başlar, ardından onu farklı kılan şeyleri ekler ya da değiştirir. Bu, C++'ın "bir-türüdür" ilişkisi için başlıca aracıdır: bir Dog bir Animal'dır, bir SavingsAccount bir BankAccount'tur.
Temel Sözdizimi: class Derived : public Base
Türetilmiş sınıf adının ardından iki nokta üst üste, bir erişim belirleyici ve temel sınıf adı yazarak miras alırsınız. En yaygın biçim public kalıtımdır.
Dog, name ya da eat()'i hiç bildirmez, ama ikisi de bir Dog nesnesi üzerinde çalışır çünkü Animal'dan miras alınmışlardır. Türetilmiş sınıf, temel sınıfın hiç bilmediği bark() gibi üyeler eklemekte serbesttir.
protected: Yalnızca Alt Sınıflar İçin Üyeler
Temel sınıfın private bir üyesine türetilmiş sınıf içinden erişilemez - kalıtım kapsüllemeyi bozmaz. Temel sınıfın iç yapısının dış dünyadan gizli ama alt sınıflara açık olmasını istediğinizde protected erişim belirleyicisini kullanın.
Üç düzeyi iç içe halkalar gibi düşünün: private "yalnızca bu sınıf", protected "bu sınıf ve onun soyundan gelenler" ve public "herkes" demektir. Tam resim için erişim belirleyicilere bakın.
Yapıcı ve Yıkıcı Sırası
Bir türetilmiş nesne, bir temel alt-nesne içerir ve türetilmiş kısım oluşturulmadan önce o temel kısmın canlı olması gerekir. Bu yüzden oluşturma önce temelden, yıkım önce türetilmişten çalışır (tam tersi sıra). Temel sınıfın yapıcı argümanlarına ihtiyacı varsa, bunları üye başlatma listesi aracılığıyla geçirirsiniz.
Çıktı bu sırayı somutlaştırır:
Animal ctor: Rex // önce temel oluşturulur
Dog ctor // sonra türetilmiş kısım
Dog dtor // ters sırayla yıkılır...
Animal dtor: Rex // ...en son temel
: Animal(n) kısmını unutursanız ve temel sınıfın varsayılan yapıcısı yoksa, kod derlenmez - C++ temel kısmın nasıl oluşturulacağını bilemez. Kendisinden miras almayı düşündüğünüz bir temel sınıf neredeyse her zaman bir yıkıcı bildirmelidir (ve bir sonraki sayfada görüleceği gibi, çoğu zaman virtual bir yıkıcı).
Override Etme: Bir Temel Metodu Yeniden Tanımlama
Bir türetilmiş sınıf, aynı imzaya sahip bir metot bildirerek miras alınan bir metodu değiştirebilir. Orijinaline hâlâ Base::method() yoluyla ulaşabilirsiniz.
Bu, çok biçimlilik değil, basit bir ad gizlemedir (name hiding): hangi describe()'in çalışacağı, değişkenin statik türüne göre derleme zamanında belirlenir. Bu kritik bir kısıtlamadır - aslında bir Circle'a işaret eden bir Shape& ya da Shape* üzerinden çağırırsanız yine de Shape::describe() alırsınız. Bunu düzeltmek virtual gerektirir; bu da bir sonraki sayfanın konusudur.
Nesne Dilimlemeye (Slicing) Dikkat
Bir temel referans ya da işaretçi bir türetilmiş nesneye başvurabildiğinden, bir türetilmiş nesneyi temel türde bir değişkene kopyalamak caziptir. Yapmayın - türetilmiş kısım dilimlenip atılır.
a, temel etiketi takmış bir Dog değil, gerçek bir Animal'dır; bu yüzden breed onda hiç var olmaz. Türetilmiş nesnelerle çok biçimli şekilde çalışmak için bir temel referans (Animal&) ya da işaretçi (Animal*) kullanmalısınız, asla bir temel değer değil. Slicing sessizdir - sorunsuz derlenir ve veriyi sessizce öylece düşürür - bu da onu, üretime kadar gönderilmesi en kolay kalıtım hatalarından biri yapar.
Kaçınılması Gereken Yaygın Hatalar
- Temel sınıfın
privateüyelerine alt sınıfta erişilebileceğini sanmak. Erişilemez. Türetilmiş sınıfın meşru olarak ihtiyaç duyduğu veriler içinprotectedkullanın ve gerçekten dahili olan durumuprivatetutun. - Temel yapıcı argümanlarını iletmeyi unutmak. Temel sınıfın varsayılan yapıcısı yoksa, onu türetilmiş yapıcının başlatma listesinde açıkça çağırmanız gerekir (
: Base(args)). - Bir türetilmiş nesneyi temel bir değere dilimlemek. Bir
Dog'u birAnimal'a kopyalamakDog'a özgü her şeyi düşürür. Onun yerine temel referansları ya da işaretçileri geçirin ve saklayın. - Kod yeniden kullanımı için kalıtımı aşırı kullanmak. Kalıtım "bir-türüdür"'i modeller. İlişki gerçekte "bir-şeye-sahiptir" ise (bir
CarbirEngine'e sahiptir), miras almak yerine bileşimi (composition) - bir üye nesne - tercih edin.
Sonraki: Sanal Fonksiyonlar
Az önce gördüğünüz override, derleme zamanında çözümlendi; bu yüzden bir temel işaretçi üzerinden çağırmak türetilmiş sürümü görmezden geldi. Bir sonraki sayfa, sanal fonksiyonlar, virtual anahtar sözcüğünü ve override'ı tanıtır - hangi metodun çalışacağına çalışma zamanı türünün karar vermesini sağlayan mekanizma; bu da gerçek çok biçimliliğin kapısını açar ve temel sınıfların neden sanal yıkıcılara ihtiyaç duyduğunu açıklar.
Sıkça Sorulan Sorular
C++'ta kalıtım nedir?
Kalıtım, var olan bir sınıfı (temel sınıf) temel alarak yeni bir sınıf (türetilmiş sınıf) tanımlamanıza olanak tanır. Türetilmiş sınıf, temel sınıfın veri üyelerini ve üye fonksiyonlarını otomatik olarak alır; yenilerini ekleyebilir veya var olan davranışı değiştirebilir. Bir "bir-türüdür" (is-a) ilişkisini modeller - bir Dog bir Animal'dır - ve C++'ın sınıf hiyerarşileri boyunca kodu yeniden kullanıp genişletmesinin başlıca yoludur.
C++'ta public ve private kalıtım arasındaki fark nedir?
public kalıtımda (class Dog : public Animal), temel sınıfın public arayüzü türetilmiş sınıfta da public kalır; böylece bir Dog bir Animal'dır ve bir Animal beklenen her yerde kullanılabilir. private kalıtımda, miras alınan üyeler private hale gelir - türetilmiş sınıf, temel sınıfın gerçekleştirimini yeniden kullanır ancak onun yerine geçemez. Public kalıtım açık ara en yaygın durumdur; private kalıtıma yalnızca "şununla-gerçekleştirilmiş" tarzı yeniden kullanım için başvurun.
C++'ta kalıtımda yapıcılar ve yıkıcılar hangi sırayla çalışır?
Yapıcılar önce temelden çalışır: türetilmiş yapıcının gövdesi yürütülmeden önce temel sınıf tamamen oluşturulur. Yıkıcılar tam tersi sırayla çalışır - önce türetilmiş, sonra temel. Bu, bir türetilmiş nesne oluşturulurken ya da yıkılırken bağımlı olduğu her parçanın zaten var olmasını (ya da hâlâ var olmasını) garanti eder.