Jediný dědičnosti
Třídy v "jediné dědičnosti," běžnou formu dědičnosti, mají pouze jeden základní třídy.Zvažte vztah, znázorněný na následujícím obrázku.
Jednoduché dědičnost jednoho grafu
Poznámka: průběh od obecného ke konkrétnímu obrázek.Jiné běžné atribut v návrhu většina hierarchie tříd je, že má odvozené třídy "druh" vztah s základní třídy.Obrázek Book je typ z PrintedDocumenta PaperbackBook je typ z book.
Jednu položku, poznámky, obrázek: Book je i odvozené třídy (z PrintedDocument) a základní třídy (PaperbackBook je odvozen od Book).Kosterní deklarace třídy hierarchie je zobrazeno v následujícím příkladu:
// deriv_SingleInheritance.cpp
// compile with: /LD
class PrintedDocument {};
// Book is derived from PrintedDocument.
class Book : public PrintedDocument {};
// PaperbackBook is derived from Book.
class PaperbackBook : public Book {};
PrintedDocumentje považován za "přímé base" Třída Book; je třída "nepřímé base" PaperbackBook.Rozdíl je, že přímá základní třída, která se zobrazí v seznamu základní deklarace třídy a nepřímé base neobsahuje.
Základní třídy, ze kterého je odvozen každá třída je deklarovaný před prohlášení odvozené třídy.Nestačí poskytnout prohlášení odkazující vpřed pro základní třídy; musí být kompletní prohlášení.
V předchozím příkladu specifikátor přístupu veřejné se používá.Význam veřejné, chráněné a soukromé dědičnost je popsán v člen Access Control.
Třída může sloužit jako základní třída pro mnoho specifických tříd, jak je znázorněno na následujícím obrázku.
Vzorek řízené Acyklické grafu
V diagramu výše uvedenou nazývá "řízeným Acyklické grafu" (nebo "DAG"), některé třídy jsou základní třídy pro více než jedné třídy odvozené.Naopak však není PRAVDA: existuje pouze jedna přímá základní třída pro všechny uvedené odvozené třídy.Graf obrázek znázorňuje strukturu "jediné dědičnost".
[!POZNÁMKA]
Řízené Acyklické grafy nejsou jedinečné do jediného dědičnosti.Používají se také k znázornění dědičnosti více grafů.Toto téma se v Vícenásobné dědění.
Odvozené třídy v dědičnosti, obsahuje člen základní třídy a nové členy, které přidáte.Následkem toho odvozené třídy mohou odkazovat na členy základní třídy (pokud tyto členy jsou předefinovány v odvozené třídě).Operátor oboru rozlišení (::) lze odkazovat na členy přímé nebo nepřímé základní třídy, když jste tyto členy podřízených v odvozené třídě.Vezměme si jako příklad:
// deriv_SingleInheritance2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;
class Document {
public:
char *Name; // Document name.
void PrintNameOf(); // Print name.
};
// Implementation of PrintNameOf function from class Document.
void Document::PrintNameOf() {
cout << Name << endl;
}
class Book : public Document {
public:
Book( char *name, long pagecount );
private:
long PageCount;
};
// Constructor from class Book.
Book::Book( char *name, long pagecount ) {
Name = new char[ strlen( name ) + 1 ];
strcpy_s( Name, strlen(Name), name );
PageCount = pagecount;
};
Všimněte si, že konstruktor pro Book, (Book::Book), má přístup k datový člen Name.V programu objekt typu Book lze vytvořit a použít takto:
// Create a new object of type Book. This invokes the
// constructor Book::Book.
Book LibraryBook( "Programming Windows, 2nd Ed", 944 );
...
// Use PrintNameOf function inherited from class Document.
LibraryBook.PrintNameOf();
Jako v předešlém, člen třídy a zděděné data a funkce se používají stejně.Pokud implementace třídy Book vyžaduje reimplementation z PrintNameOf funkce, funkce, které patří Document třídy lze volat pouze pomocí oboru rozlišení (::) operátor:
// deriv_SingleInheritance3.cpp
// compile with: /EHsc /LD
#include <iostream>
using namespace std;
class Document {
public:
char *Name; // Document name.
void PrintNameOf() {} // Print name.
};
class Book : public Document {
Book( char *name, long pagecount );
void PrintNameOf();
long PageCount;
};
void Book::PrintNameOf() {
cout << "Name of book: ";
Document::PrintNameOf();
}
Ukazatele a odkazy na odvozené třídy může být implicitně převeden na ukazatele a odkazy na jejich základní třídy Pokud přístupná a jednoznačné základní třídy.Následující kód ukazuje tento pojem pomocí ukazatele (totéž platí pro odkazy):
// deriv_SingleInheritance4.cpp
// compile with: /W3
struct Document {
char *Name;
void PrintNameOf() {}
};
class PaperbackBook : public Document {};
int main() {
Document * DocLib[10]; // Library of ten documents.
for (int i = 0 ; i < 10 ; i++)
DocLib[i] = new Document;
}
Různé typy jsou vytvořeny v předchozím příkladu.Ale protože tyto typy jsou odvozeny z Document třídy, je implicitní převod na Document *.Výsledkem je DocLib je "heterogenní seznam" (seznam, ve kterém nemají všechny objekty jsou stejného typu) obsahující různé druhy objektů.
Protože Document třída má PrintNameOf funkce tisku název každé knihy v knihovně, ačkoli mohou vynechat, některé informace specifické pro daný typ dokumentu (počet stránek Book, počet bajtů pro HelpFile, atd).
[!POZNÁMKA]
Vynucení základní třída implementovat funkci jako PrintNameOf je často není optimální.Funkce virtuální nabízí další možnosti návrhu.