Vea este video para comprender el concepto de clases generales y más especializadas.
Herencia - La relación "Es A"
En el modelado hablamos de «especialización». La implementación de esta relación en un lenguaje de programación utiliza el concepto de herencia, en el que una nueva clase (la subclase) se deriva de una clase existente (la clase superior). Una prueba fiable para ver si existe una relación de herencia genuina entre dos clases es intentar decir "una subclase es una clase superior". Si esta afirmación es claramente verdadera, existe una relación de herencia. Si claramente no es cierto, o incluso suena un poco extraño, usted no tiene una relación de herencia y no debe implementar una ya que probablemente causará problemas más abajo en la línea. Al probar nuestro modelo, podemos decir definitivamente que "un avión de carga es un avión " y "un avión de pasajeros es un avión".

Una clase que hereda de una clase superior contiene automáticamente todos los componentes de la clase superior. Así, por ejemplo, la clase de avión de pasajeros tiene un fabricante y un tipo al igual que un avión. Esto no debería sorprender, ya que un avión de pasajeros es un avión. Lo que al principio puede parecer sorprendente es que la clase de avión de pasajeros no pueda acceder a su propio fabricante y tipo. Ello se debe al hecho de que son atributos privados de la clase superior y, como tales, no son accesibles para la subclase. Más adelante aprenderá una forma de permitir que una subclase acceda a los componentes de una clase superior sin hacerlos totalmente públicos.
Definición de una relación de herencia
En ABAP puede implementar la herencia utilizando el suplemento INHERITING FROM en la definición de clase sentencia. En este ejemplo, la clase de avión de pasajero se define como una subclase de la clase de avión. Tenga en cuenta que la subclase conoce su clase superior, pero la clase de avión no tiene idea de qué subclases tiene (si las hay).

Una subclase puede incluir solo una clase superior directa.
Una clase superior: cualquier número de subclases
La clase de avión puede tener cualquier número de subclases, pero no sabe nada de ellas.

Cada subclase tiene una única clase superior directa. Conoce su clase superior, pero no tiene información sobre ninguna clase hermana (otras clases que se derivan de la misma clase superior). En nuestro ejemplo, la clase de avión de pasajeros no tiene conocimiento de la clase de avión de carga.
Cómo ampliar una subclase

Una vez que haya declarado una subclase, debe añadirle componentes nuevos o modificar los componentes existentes. Esto es lo que convierte la mera copia de la clase de avión en un avión de pasajeros o un avión de carga. Gracias a la herencia, no es necesario implementar la clase desde cero; simplemente la amplía con los nuevos componentes que necesita.
Existen tres maneras de realizar esta tarea:
Agregar nuevos componentes: puede declarar nuevos atributos, tipos, constantes y métodos en la clase. Sus nombres no debe estar en conflicto con otros nombres que ya se han utilizado para declarar componentes en la clase superior. También debe asegurarse de que los componentes nuevos solo son relevantes para la subclase y no para todas las especializaciones de la clase superior. Si declara un atributo o método nuevo que, por lo general, es relevante, deberá moverlo a la clase superior.
Redefinir métodos: cuando llama un método heredado, el sistema de tiempo de ejecución ejecuta la implementación del método desde la clase superior. Sin embargo, esta implementación no puede tener en cuenta componentes nuevos que ha declarado en la subclase. En este caso, se puede volver a definir el método. Esto significa que puede asignarle una implementación nueva que es relevante para la subclase.
Añadir un constructor nuevo: Los constructores garantizan que las nuevas instancias de la clase se initalicen correctamente. Cuando crea una instancia de una subclase, el sistema de tiempo de ejecución siempre ejecuta el constructor de la clase superior. Esto garantiza, por ejemplo, que un avión de pasajeros tenga un fabricante y un tipo del mismo modo que cualquier otro avión. Sin embargo, el constructor de la clase superior no puede inicializar atributos de la subclase, ya que no sabe que existen. Por este motivo, puede definir un constructor nuevo para la subclase.
Declaración de componentes nuevos

Puede ampliar una subclase declarando componentes nuevos. Estas son visibles para la propia clase, pero no para la clase superior, y tampoco para ninguna otra clase que herede de la misma clase superior. Por lo tanto, debe considerar si los componentes nuevos solo son relevantes en la clase actual o si realmente se deben declarar en la clase superior.
Componentes protegidos
Aunque una subclase contenga todos los atributos de su clase superior, no está permitido acceder a los componentes privados directamente por sí misma. En ocasiones esto resulta necesario; sin embargo, en otras ocasiones es necesario que una clase superior deje que sus subclases accedan a atributos o métodos concretos sin hacerlos totalmente públicos. Puede hacerlo declarándolos en la sección protegida. Los componentes protegidos no solo están visibles dentro de la propia clase, sino también para todas las subclases.

En la definición de clase se introduce la sección protegida mediante la sentencia PROTECTED SECTION. Siempre debe declarar las secciones de visibilidad en la secuencia PUBLIC SECTION, PROTECTED SECTION, PRIVATE SECTION.
Puede mover un componente existente de una clase utilizando una corrección rápida. Para ello, sitúe el cursor en el nombre del componente en ADT y pulse Ctrl + 1 y, a continuación, seleccione la solución rápida Proteger <elemento>.
Mover un componente privado a la sección protegida es una modificación compatible: ha ampliado la visibilidad del componente. Sin embargo, proteger un componente público es una modificación incompatible y podría provocar errores de sintaxis. Esto se debe a que ha restringido la visibilidad del componente que ya podría haberse utilizado fuera de la jerarquía de herencia.
Redefinición de métodos
Las clases superiores suelen contener métodos que desea utilizar en una subclase, pero sus implementaciones son inapropiadas, ya que no tienen en cuenta la naturaleza concreta de la subclase. Por ejemplo, el método get_attributes de la clase de avión no puede devolver atributos definidos en la clase de avión de pasajero. Sin embargo, la clase de avión de pasajeros aún necesita un método get_attributes.

En ABAP, puede resolver este problema redefiniendo el método de instancia get_attributes. Al redefinir un método, puede escribir una nueva implementación para él en la subclase que tiene en cuenta cosas que solo la subclase puede saber. Sin embargo, la definición del método sigue siendo exactamente la misma. Debe seguir estas reglas:
- El método conserva el mismo nombre.
- Puede indicar que desea redefinir el método declarándolo en la subclase con el suplemento REDEFINITION.
- El método tiene la misma visibilidad que en la clase superior.
- No debe cambiar la firma del método.
No puede redefinir un método estático.
Implementación de la redefinición
Al implementar la redefinición de un método, puede llamar la implementación en la clase superior. Esto se consigue mediante la referencia de objeto implícita «súper», que muestra la clase superior dentro de la instancia actual. De este modo, puede reutilizar la implementación de método de la clase superior y luego añadirla en su propia implementación.

No es necesario declarar la variable de referencia «súper». Está disponible automáticamente dentro de la implementación o de los métodos redefinidos.
Llamar el método en la clase superior de esta manera es opcional. A veces será una buena idea, mientras que en otras ocasiones no aportará nada.
Nueva definición de constructor

En una subclase puede definir un constructor nuevo. A diferencia de las redefiniciones de método, un constructor puede tener su propia firma. La firma de un constructor suele contener los mismos parámetros que el constructor de la clase superior, además de sus propios parámetros nuevos. Esto se debe a que el nuevo constructor de instancia tiene dos tareas: primero llamar al constructor de la clase superior y, a continuación, encargarse de initalizar sus propios atributos que son específicos de la subclase.
De la misma manera que se puede definir un constructor nuevo, también puede definir una constructor estático nuevo en una subclase.
Rol del constructor
El constructor de una subclase tiene dos funciones: debe asegurarse de que los componentes de la clase superior se inicialicen correctamente, y después de eso, puede establecer los valores iniciales de los atributos de subclase.

En nuestro ejemplo, dado que un avión de pasajeros es un avión, no puede haber ninguna instancia de avión de pasajeros a menos que el constructor de la clase de avión se haya ejecutado correctamente para establecer el fabricante y el tipo del nuevo avión de pasajeros. Solo después de esto, la clase de avión de pasajeros puede fijar sus propios atributos.
Por lo tanto, el constructor de la subclase debe tener la capacidad de fijar no solo sus propios atributos, sino de transferir los valores requeridos para al constructor de la clase superior. Este es el motivo por el que la firma del constructor en la subclase suele contener toda la firma del constructor necesaria para llamar.
Secuencia de implementación de constructor nuevo

En la implementación del constructor nuevo existe una secuencia concreta de operaciones que debe observar. El evento más importante es la llamada al constructor de la clase superior. Esto es obligatorio y se llama el método mediante la referencia implícita «súper» del mismo modo que puede hacerlo al llamar la implementación original de un método redefinido. Una vez más, no es necesario declarar explícitamente super.
Antes de haber llamado el constructor de la clase superior, no debe tratar los componentes de instancia de la instancia que está en construcción. Puede tratar los componentes estáticos de la clase y verificar la exactitud de los parámetros de importación del constructor. Si no son correctos, cree una excepción.
Una vez que el constructor de la clase superior se ha ejecutado correctamente, puede tratar los componentes de instancia de su nueva instancia.
Secuencia de llamadas de constructor
El gráfico ilustra la secuencia en la que se llaman los constructores estáticos y los constructores de instancia. El ejemplo supone que un programa desea instanciar la clase de avión de pasajero y que la clase de avión no se ha abordado previamente.

Cuando el programa intenta crear una instancia de la clase de avión pasajero, el sistema de tiempo de ejecución llama automáticamente a los constructores estáticos secuencialmente, empezando por la parte superior de la jerarquía de herencia. Una vez ejecutados todos los constructores estáticos, el sistema del tiempo de ejecución llama el constructor de instancia de la subclase, que, a su vez, llama el constructor de instancia de la clase superior.



