- Encapsulación y extensión de tipos
- Herencia
- Polimorfismo
- Sobrecarga
- Funciones virtuales
- Miembros estáticos de una clase
- Plantillas de funciones
- Plantillas de clases
- Clases abstractas
Herencia
La particularidad de POO es la promoción de reuso del código utilizando los mecanismos de herencia. Una clase nueva se crea de una ya existente que se llama la clase base (superclase). La clase derivada (subclase) utiliza los elementos de la clase base. La clase derivada usa los elementos de la clase base, aunque también puede modificar y completarlos.
Muchos tipos son variaciones de los temas ya existentes. A menudo resulta muy agotador elaborar un código nuevo para cada uno de ellos. Además, un código nuevo supone errores nuevos. La clase derivada hereda la descripción de la clase base, siendo innecesario volver a crear y comprobar el código. Las relaciones de herencia se representan en una forma jerárquica.
La jerarquía es un método que permite copiar los elementos en toda su diversidad y complejidad. Ella introduce la clasificación de objetos. Por ejemplo, en la tabla periódica de los elementos hay gases. Ellos poseen propiedades inherentes a todos los elementos del sistema.
Los gases inertes es la siguiente subclase importante. La jerarquía consiste en que el gas inerte, como por ejemplo el argón, es un gas, y en su lugar el gas es un elemento del sistema. Este tipo de jerarquía permite explicar fácilmente el comportamiento de los gases inertes. Sabemos que sus átomos contienen protones y electrones, lo que es cierto para los demás elementos.
Sabemos que se encuentran en el estado gaseoso con la temperatura interior, igual que todos los gases. Sabemos que ningún gas de la subclase de gases inertes entra en la reacción química común con ninguno de los elemento, y esta es la propiedad de todos los gases inertes.
Vamos a ver la jerarquía en el ejemplo de las figuras geométricas. Para describir la variedad de figuras simples (círculo, triángulo, rectángulo, cuadrado, etc.) es mejor crear una clase base (TDA), que resulta ser el antecesor de todas las clases derivadas.
Vamos a crear la clase base CShape que contiene sólo los miembros más comunes que describen la figura. Estos miembros describen las propiedades características de cualquier figura, es decir, tipo de figura y las coordenadas del punto principal de enlace.
Ejemplo:
//--- Clase base Figura
|
Luego vamos a crear nuevas clases derivadas de la clase base en las cuales vamos a añadir campos necesarios que especifican cada clase en particular. Para la figura Circle(círculo) hace falta añadir un miembro que contiene el valor del radio. La figura Quadrate (cuadrado) se caracteriza por el valor del lado del cuadrado. Por lo tanto, las clases derivadas, heredadas de la clase base CShape, serán declaradas como sigue:
//--- clase derivada Círculo
|
Para el cuadrado la declaración de la clase es similar:
//--- clase derivada Cuadrado
|
Cabe señalar que durante la creación de un objeto primero se llama al constructor de la clase base, y luego al constructor de la clase derivada. Cuando se destruye un objeto, primero se llama al destructor de la clase derivada, y luego al destructor de la clase base.
De esa manera, al declarar en la clase base los miembros más generales, podemos añadir miembros adicionales en las clases derivadas, los que precisan una clase en concreto. La herencia permite crear potentes bibliotecas de código que pueden ser utilizadas varias veces y en repetidas ocasiones.
La sintaxis de crear una clase derivada de una ya existente es como sigue:
class nombre_de_clase :
|
Uno de los aspectos de una clase derivada es la visibilidad (abertura) de sus miembros-herederos. Las palabras claves public, protected y private se utilizan para indicar el nivel de acceso de los elementos de la clase base para la clase derivada. El uso de la palabra clave private seguida de dos puntos en el encabezado de la clase derivada significa que los miembros protegidos y abiertos (protected y public) de la clase base CShape deberían ser heredados como elementos protegidos y abiertos de la clase derivada CCircle.
Los miembros privados de la clase base no están disponibles para la clase derivada. La herencia pública también significa que las clases derivadas (CCircle y CSquare) son CShape. Es decir, el cuadrado (CSquare) es la figura (CShape) pero la figura no tiene que ser obligatoriamen6te un cuadrado.
La clase derivada es una modificación de la clase base; hereda los miembros protegidos y públicos de la clase base. Los constructores y destructores de la clase base no pueden ser heredados. A menudo a la clase derivada se añaden nuevos miembros como complemento a los miembros de la clase base.
La clase derivada puede incluir la implementación de las funciones-miembro diferente de la clase base. Eso no tiene nada que ver con la sobrecarga cuando el significado del nombre de la función puede ser distinto para diferentes signaturas.
Con la herencia protegida los miembros públicos y protegidos de la clase base se hacen miembros protegidos de la clase derivada. Con la herencia privada los miembros públicos y protegidos de la clase base se hacen miembros privados de la clase derivada.
Con la herencia protegida y privada la relación de que "un objeto de clase derivada es un objeto de clase base" no es cierta. La herencia protegida y privada se encuentran muy raras veces, y hay que usar cada una de ellas con mucho cuidado.
Hay que entender que el tipo de herencia (public, protected o private) de ninguna manera influye en los modos de acceso a los miembros de las clases base en la jerarquía de la herencia desde una clase derivada (un heredero). Sea como sea el tipo de herencia, desde las clases derivadas estarán disponibles sólo los miembros de la clase base declarados con los especificadores de acceso public y protected. Veremos lo arriba mencionado en un ejemplo:
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
|
En el ejemplo citado, la clase CBaseClass tiene sólo un método público, es el constructor. Los constructores se llaman automáticamente cuando se crea un objeto de la clase. Por eso no hay ninguna manera de llamar al miembro privado m_member, ni tampoco al método protegido Member() desde fuera. Pero en caso de la herencia pública (public), el método Member() de la clase base estará disponible desde las clases derivadas.
En caso de la herencia protegida (protected), todos los miembros de la clase base con el acceso público y protegido se hacen protegidos. Esto significa que si los miembros-datos y métodos públicos de la clase base estaban disponibles desde fuera, entonces ahora en caso de la herencia protegida ellos estarán disponibles sólo desde las clases del heredero y de sus posteriores clases derivadas.
//+------------------------------------------------------------------+
|
En este ejemplo se muestra que los métodos SetPI() y GetPi() en la clase base CBaseMathClass son públicos y están disponibles para la llamada desde cualquier parte del programa. Pero al mismo tiempo, para su derivada CProtectedChildClass las llamadas a estos métodos se puede realizar sólo desde los métodos de la misma clase CProtectedChildClass o sus clases derivadas.
En caso de la herencia privada (private), todos los miembros de la clase base con el acceso public y protected se hacen privados, y en caso de posteriores herencias resulta imposible llamarlos.
En MQL5 no hay herencia múltiple.
Véase también