Condividi tramite


Ereditarietà singola

“Nell'ereditarietà singola, un„ forma più comune di ereditarietà, classi hanno solo una classe base.Si consideri la relazione illustrata nella figura che segue.

grafico semplice di Singolo-Ereditarietà

Rappresentazione grafica Single_Inheritance semplice

Si noti la progressione da generale a specifico nella figura.Un altro attributo comune di ricerca nella progettazione della maggior parte delle gerarchie di classi è che la classe derivata ha un “tipo„ di una relazione con la classe base.Nella figura, a Book è un tipo di oggetto PrintedDocumente PaperbackBook è un tipo di oggetto book.

Un altro elemento della nota nella figura: Book è una classe derivata (da PrintedDocument) e una classe base (PaperbackBook deriva da Book).Una dichiarazione scheletrica della gerarchia di classi è illustrata nell'esempio seguente:

// 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 {};

PrintedDocument è considerata una classe “base„ diretta a Book; è una classe “base„ indiretta a PaperbackBook.La differenza è che una classe base diretta verrà visualizzato nell'elenco di base di una dichiarazione di classe e una classe base indiretta contrario.

La classe base da cui ogni classe è derivata viene dichiarata prima della dichiarazione della classe derivata.Non è sufficiente fornire una dichiarazione avanti-di riferimento per una classe base; deve essere una dichiarazione completa.

Nell'esempio precedente, l'identificatore di accesso pubblico viene utilizzato.Il significato pubbliche, i protetti e ereditarietà privata viene descritto in. Controllo di accesso al membro.

La classe può essere utilizzata come classe base per molte classi specifiche, come illustrato nella figura seguente.

Esempio del grafico aciclico diretto

Esempio di rappresentazione grafica acicilica diretta

Nel diagramma riportato sopra, denominato “ha diretto il grafico aciclico„ (o “DAG„), alcune classi sono classi base per più di uno classe derivata.Tuttavia, l'opposto non è vera: esiste una sola classe base diretta per qualsiasi classe derivata specificata.Il grafico nella figura raffigura “struttura dell'ereditarietà singola„.

[!NOTA]

I grafici diretti aciclici non sono univoci scegliere l'ereditarietà.Vengono inoltre utilizzati per rappresentare i grafici di ereditarietà multipla.In questo argomento viene analizzato in ereditarietà multipla.

Nell'erediterietà, la classe derivata contiene membri della classe base e tutti i nuovi membri che si aggiunge.Di conseguenza, una classe derivata può fare riferimento ai membri della classe base (a meno che i membri vengano ridefinite nella classe derivata.L'operatore di risoluzione dell'ambito (::) può essere utilizzato per fare riferimento ai membri delle classi di base dirette o indirette quando tali membri sono stati ridefinite nella classe derivata.Si consideri l'esempio seguente:

// 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;
};

si noti che il costruttore per Book, (Book::Book), dispone di accesso al membro dati, Name.in un programma, un oggetto di tipo Book può essere creato e utilizzato come segue:

//  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();

Mentre nell'esempio precedente viene illustrato, il membro della classe e i dati e le funzioni ereditati vengono utilizzati in modo identico.Se l'implementazione di classe Book richieste per un reimplementation di PrintNameOf funzione, la funzione che appartiene a Document la classe può essere chiamato solo tramite la ambito-risoluzione (::operatore):

// 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();
}

I puntatori e i riferimenti alle classi derivate possono essere convertiti in modo implicito a puntatori ai riferimenti alle classi di base se c " è una classe base accessibile e ambigua.Il codice seguente viene illustrato questo concetto utilizzo dei puntatori (lo stesso principio vale per i riferimenti):

// 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;
}

Nell'esempio precedente, i tipi differenti vengono creati.Tuttavia, poiché questi tipi vengono derivati da Document classificare, esiste una conversione implicita a Document *.di conseguenza, DocLib è “elenco eterogeneo„ (un elenco in cui non tutti gli oggetti sono dello stesso tipo) contenente i diversi tipi di oggetti.

Poiché Document la classe dispone di un oggetto PrintNameOf funzione, è possibile stampare il nome di ogni libro nella raccolta, anche se può omettere alcune delle informazioni specifiche del tipo di documento (conteggio della pagina per Book, numero di byte da HelpFile, e così via).

[!NOTA]

Forzare la classe base per implementare una funzione come PrintNameOf non è spesso una migliore progettazione.funzioni virtuali offre alternative di progettazione.

Vedere anche

Riferimenti

Cenni preliminari sulle classi derivate

Ereditarietà multipla