privada polimorfismo herencia derivada clase c++ inheritance private public protected

polimorfismo - herencia privada c++



C++ ¿por qué usar herencia pública, privada o protegida? (4)

La respuesta a esta pregunta se refiere a las interfaces de clase y a la encapsulación de datos, en lugar de a las capacidades del lenguaje.

Los casos de uso de herencia protegida y privada son bastante limitados, ya que a menudo hay otras opciones disponibles que resuelven mejor el problema (como el uso de la composición, en lugar de la herencia). Sin embargo, hay momentos en los que necesariamente debe heredar de algún tipo (por ejemplo, para interactuar con una biblioteca de terceros), pero preferiría (por razones relacionadas con la interfaz de usuario de su clase) ocultar la mayoría de los miembros heredados de la base. clase de los usuarios de tu nuevo tipo. Un escenario típico sería cuando necesita que su tipo tenga las funciones miembro de una cierta clase para uso interno, pero rompería la lógica de su nuevo tipo si se llama desde fuera de la clase.

En estas situaciones, debe usar herencia private o protected (dependiendo de si la interfaz debe restringirse de manera similar a otras clases derivadas o no).

Tenga en cuenta, sin embargo, que esto es solo (fuertemente) insinuando a los usuarios de su clase cómo deberían usarlo. Está adaptando su interfaz pública para ocultar ciertas características que eran públicas en su clase base. Esto estrictamente hablando no impide que las personas accedan a estos miembros, ya que cualquiera puede lanzar un puntero a su clase derivada a un puntero a la base y llegar a los recursos "ocultos" de esa manera.

Bueno, hay suficiente información sobre este tema. Por ejemplo, este hilo fue muy claro para mí: diferencia entre herencia privada, pública y protegida

Excepto un punto; ¿Por qué es útil?


Usa herencia pública para reflejar una relación is-a . Este es el uso principal para la herencia, especialmente en combinación con funciones virtuales. Permite la reutilización de la interfaz, no solo del código antiguo por código nuevo, sino también la reutilización de código nuevo por código antiguo. (debido al envío de funciones virtuales en tiempo de ejecución).

En circunstancias excepcionales, utilice la herencia privada para reflejar una relación is-applied-in-terms-of . Este es un patrón comúnmente usado en exceso, a menudo el objetivo equivalente se puede alcanzar a través de la composición (teniendo la clase base aspirante como un miembro de datos). Otro inconveniente es que fácilmente puede tener herencia múltiple de la misma clase base (dos o más eliminadas) lo que lleva al llamado Problema Diamante .

Evite usar herencia protegida , sugiere que su interfaz de clase depende del cliente (clases derivadas frente al mundo). A menudo, esto se debe a que las clases tienen múltiples responsabilidades, lo que sugiere que una refactorización en clases separadas es apropiada.


Privado: a los miembros privados de una clase solo se puede acceder desde funciones de clase, constructores y destructores. El cliente que usará tu clase no podrá acceder a ellos. Por lo tanto, si, por ejemplo, está implementando una clase de lista y desea realizar un seguimiento del tamaño de la lista, entonces debe tener una variable privada ( listSizeP por ejemplo). Haga esto porque no desea que el cliente pueda modificar el tamaño de la lista sin insertar elementos.

Público: el cliente también puede acceder a los miembros públicos. En el ejemplo de lista mencionado anteriormente, las funciones como insert y erase deben ser públicas.

Protegido: a los miembros protegidos de una clase, como los miembros privados, se puede acceder solo desde las funciones de la clase, pero también se puede acceder mediante clases heredadas por esta clase (en realidad depende de la forma en que la clase derivada herede la base. herencia pública, entonces la clase derivada no puede acceder a los miembros privados de la clase base. Es por eso que la forma más común de heredar es la herencia pública). Ejemplo:

#include <iostream> using namespace std; class Base { public: int num; public: Base(int x=0) : num(x) {} }; class Derived : public Base { public: Derived(int x=0) : Base(x) {} void tell() { cout << "num: " << num << endl; } }; int main() { Derived D(4); D.tell(); // would cause error if num was private return 0; }


Se trata de la Encapsulación de Datos .

http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

Concepto de encapsulación

Es bueno proteger los datos internos de sus clases de otras clases. Beneficios incluidos:

  • otras clases tienen que pasar por los mecanismos de acceso apropiados conocidos (por ejemplo, métodos) para acceder a su clase y no pueden moverse con los internos de su clase directamente (y por lo tanto potencialmente poner a su clase en un estado desconocido y roto)
  • puedes cambiar el funcionamiento interno de tu clase y saber que las otras clases no se romperán como resultado
  • reducir los puntos de contacto externos visibles con una clase hace que tus clases sean más simples de usar y comprender

Tener la opción de usar protected lugar de private también hace que su código sea más fácil de extender a través de subclases.