Compartir a través de


Herencia simple

En “herencia única,” un formulario común de herencia, clases sólo tiene una clase base.Considere la relación mostrada en la ilustración siguiente.

Solo-Herencia simple Gráfico

Gráfico simple de Single_Inheritance

Observe la progresión del programa concreto en la ilustración.Otro atributo común encontrado en el diseño de las jerarquías de clases es que la clase derivada tiene una “clase” de relación con la clase base.En la ilustración, Book es una clase de PrintedDocument, y PaperbackBook es una clase de book.

Otro elemento de interés en la figura: Book es una clase derivada (de PrintedDocument) y una clase base (PaperbackBook es derivado de Book).Una declaración estructural de esta jerarquía de clases se muestra en el ejemplo siguiente:

// 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 se considera “dirige una clase de base” a Book; es una clase “base” indirecta a PaperbackBook.La diferencia es que una clase base directa aparece en la lista base de una declaración de clase y no hace una base indirecta.

La clase base de la que cada clase es derivada se declara antes de la declaración de clase derivada.No es suficiente para proporcionar una declaración delantero-que hace referencia una clase base; debe ser una declaración completa.

En el ejemplo anterior, el especificador Público de acceso.El significado de public, protected, y herencia privada se describe en Control de acceso a miembros.

Una clase puede actuar como clase base para muchas clases específicas, como se muestra en la ilustración siguiente.

Ejemplo de Directed Graph Acyclic

Ejemplo Directed Acyclic Graph

En el diagrama anterior, denominado “dirigió el gráfico acíclico” (o “DAG”), algunas de las clases son clases base para más de una clase derivada.Sin embargo, el inverso no es cierta: sólo hay una clase base directa para cualquier clase derivada especificada.El gráfico en la figura describe una estructura de “herencia única”.

[!NOTA]

Gráficos acíclicos dirigidos no son únicos selección herencia.También se usan para describir los gráficos de herencia múltiple.En este tema se cubre en herencia múltiple.

En la herencia, la clase derivada contiene miembros de la clase base más cualquier nuevo miembro que agregue.Como resultado, una clase derivada puede hacer referencia a miembros de clase base (a menos que redefine esos miembros en la clase derivada).El operador de resolución de ámbito (::) puede utilizarse para hacer referencia a los miembros de clases base directas o indirectas cuando ha vuelto a definir esos miembros en la clase derivada.Considere este ejemplo:

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

Observe que el constructor para Book, (Book::Book), tiene acceso al miembro de datos, Name.En un programa, un objeto de Book escrito puede crear y utilizar como sigue:

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

Mientras que el ejemplo anterior muestra, utilizan el miembro de clase y los datos y las funciones heredados idéntico.Si la implementación para las llamadas de Book de clase de un reimplementation de la función de PrintNameOf , la función correspondiente a la clase de Document solo se puede llamar mediante el operador de resolución de ámbito (::):

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

Los punteros y las referencias a las clases derivadas se pueden convertir implícitamente a los punteros y las referencias a sus clases base si hay una clase base accesible, inequívoca.El código siguiente muestra este concepto mediante punteros (el mismo principio aplica a referencias):

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

En el ejemplo anterior, crean a tipos diferentes.Sin embargo, dado que estos tipos son todos derivados de la clase de Document , hay una conversión implícita a Document *.Como resultado, DocLib es una “lista heterogénea” (una lista en la que no todos los objetos son del mismo tipo) que contiene diferentes tipos de objetos.

Dado que la clase de Document tiene una función de PrintNameOf , puede imprimir el nombre de cada libro en la biblioteca, aunque puede omitir algo de información específica del tipo de documento (recuento de Book, número de la página de bytes para HelpFile, etc.).

[!NOTA]

Forzar la clase base para implementar una función como PrintNameOf no suele ser el mejor diseño.funciones virtuales proporciona otras alternativas de diseño.

Vea también

Referencia

Información general de clases derivadas

Herencia múltiple