2. Los métodos heredados se pueden usar directamente tal como son. ... Podemos
declarar nuevos métodos en la subclase que no están en la superclase. Podemos
escribir un constructor de subclase que invoca el constructor de la superclase, ya sea
implícitamente o mediante la palabra clave super.
La herencia es un pilar importante de OOP (Programación Orientada a Objetos). Es el
mecanismo en Java por el cual una clase permite heredar las características (atributos y
métodos) de otra clase. Aprenda más a continuación.
En el lenguaje de Java, una clase que se hereda se denomina superclase. La clase que hereda
se llama subclase. Por lo tanto, una subclase es una versión especializada de una superclase.
Hereda todas las variables y métodos definidos por la superclase y agrega sus propios
elementos únicos.
3. Terminología importante
Superclase: la clase cuyas características se heredan se conoce como superclase (o
una clase base o una clase principal).
Subclase: la clase que hereda la otra clase se conoce como subclase (o una clase
derivada, clase extendida o clase hija). La subclase puede agregar sus propios campos
y métodos además de los campos y métodos de la superclase.
Reutilización: la herencia respalda el concepto de “reutilización”, es decir, cuando
queremos crear una clase nueva y ya hay una clase que incluye parte del código que
queremos, podemos derivar nuestra nueva clase de la clase existente. Al hacer esto,
estamos reutilizando los campos/atributos y métodos de la clase existente.
4. ¿Qué es Herencia?
Podemos definir la herencia como la capacidad de crear clases que adquieren de
manera automática los miembros (atributos y métodos) de otras clases que ya existen,
pudiendo al mismo tiempo añadir atributos y métodos propios.
JAVA SOPORTA LA HERENCIA PERMITIENDO UNA CLASE A INCORPORAR OTRA
CLASE EN SU DECLARACIÓN. ESTO SE HACE MEDIANTE EL USO DE LA PALABRA
CLAVE EXTENDS. POR LO TANTO, LA SUBCLASE SE AÑADE (SE EXTIENDE) A LA
SUPERCLASE.
5. Ventajas de la Herencia
Entre las principales ventajas que ofrece la herencia en el desarrollo de aplicaciones, están:
Reutilización del código: En aquellos casos donde se necesita crear una clase que, además de
otros propios, deba incluir los métodos definidos en otra, la herencia evita tener que reescribir
todos esos métodos en la nueva clase.
Mantenimiento de aplicaciones existentes: Utilizando la herencia, si tenemos una clase con
una determinada funcionalidad y tenemos la necesidad de ampliar dicha funcionalidad, no
necesitamos modificar la clase existente (la cual se puede seguir utilizando para el tipo de
programa para la que fue diseñada) sino que podemos crear una clase que herede a la primera,
adquiriendo toda su funcionalidad y añadiendo la suya propia.
6. Control de Acceso a Miembros en Herencia
A menudo una variable de instancia de una clase se declarará privada () para evitar su uso no autorizado o
alteración. Heredar una clase no anula la restricción de acceso privado. Por lo tanto, aunque una subclase incluye
a todos los miembros de su superclase, no puede acceder a los miembros de la superclase que se han declarado
privados
7. Ejemplo:
Por ejemplo, si, como se muestra aquí, la base y
la altura se vuelven privados
en DosDimensiones, entonces Triangulo no
podrá acceder a ellos.
8. La clase Triangulo no se compilará porque la referencia a la base y altura dentro del
método area() causa una infracción de acceso. Como la base y altura se declaran privados, solo son
accesibles para otros miembros de su propia clase. Las subclases no tienen acceso a ellas.
Recuerde que un miembro de la clase que ha sido declarado private seguirá siendo privado para su
clase. No es accesible por ningún código fuera de su clase, incluidas las subclases.
Al principio, podría pensar que el hecho de que las subclases no tengan acceso a los miembros privados
de las superclases es una restricción seria que impediría el uso de miembros privados en muchas
situaciones. Sin embargo, eso no es verdad. Los programadores de Java suelen utilizar métodos de
acceso para proporcionar acceso a los miembros privados de una clase.
9. Constructores y herencia
En una jerarquía, es posible que tanto las superclases como las subclases tengan sus propios
constructores. Esto plantea una pregunta importante: ¿qué constructor es responsable de
construir un objeto de la subclase, el de la superclase, el de la subclase o ambos? La respuesta
es esta: el constructor para la superclase construye la porción de la superclase del objeto, y el
constructor para la subclase construye la parte de la subclase.
Esto tiene sentido porque la superclase no tiene conocimiento ni acceso a ningún elemento en una
subclase. Por lo tanto, su construcción debe estar separada. En la práctica, la mayoría de las clases
tendrán constructores explícitos (no predeterminados). Aquí verá cómo manejar esta situación.
Cuando solo la subclase define un constructor, el proceso es sencillo: simplemente construye el objeto
de la subclase. La porción de superclase del objeto se construye automáticamente utilizando su
constructor predeterminado. Por ejemplo, aquí hay un programa para Triangulo que define un
constructor. También hace que el estilo sea privado, ya que ahora lo establece el constructor.
10. Tipos de herencia en
Java
A continuación se muestran los diferentes tipos de herencia
compatibles con Java.
Herencia única: en la herencia única, las subclases
heredan las características de solo una superclase. En la
imagen a continuación, la clase A sirve como clase base
para la clase derivada B.
11. Herencia Multinivel: en la herencia multinivel, una
clase derivada heredará una clase base y, además, la
clase derivada también actuará como la clase base de
otra clase. En la imagen inferior, la clase A sirve como
clase base para la clase derivada B, que a su vez
sirve como clase base para la clase derivada C. En
Java, una clase no puede acceder directamente a los
miembros de los “abuelos”.
12. Herencia Jerárquica: en la herencia jerárquica, una
clase sirve como una superclase (clase base) para
más de una subclase. En la imagen inferior, la clase A
sirve como clase base para la clase derivada B, C y D.
13. Herencia Múltiple (a través de interfaces): en
Herencia múltiple, una clase puede tener más de una
superclase y heredar características de todas las
clases principales. Tenga en cuenta que Java no
admite herencia múltiple con clases. En Java,
podemos lograr herencia múltiple solo a través de
Interfaces. En la imagen a continuación, la Clase C se
deriva de la interfaz A y B.
14. Herencia Híbrida (a través de Interfaces): Es una
mezcla de dos o más de los tipos de herencia
anteriores. Como Java no admite herencia múltiple
con clases, la herencia híbrida tampoco es posible con
clases. En Java, podemos lograr herencia híbrida
solo a través de Interfaces.
15. Datos importantes acerca de la herencia
en Java
Superclase predeterminada: excepto la clase Object, que no tiene superclase, cada clase tiene una y
solo una superclase directa (herencia única). En ausencia de cualquier otra superclase explícita, cada
clase es implícitamente una subclase de la clase Object.
La superclase solo puede ser una: una superclase puede tener cualquier cantidad de subclases.
Pero una subclase solo puede tener una superclase. Esto se debe a que Java no admite herencia
múltiple con clases. Aunque con interfaces, la herencia múltiple es compatible con java.
Heredar constructores: una subclase hereda todos los miembros (campos, métodos y clases
anidadas) de su superclase. Los constructores no son miembros, por lo que no son heredados por
subclases, pero el constructor de la superclase puede invocarse desde la subclase.
Herencia de miembros privados: una subclase no hereda los miembros privados de su clase
principal. Sin embargo, si la superclase tiene métodos públicos o protegidos (como getters y setters)
para acceder a sus campos privados, estos también pueden ser utilizados por la subclase.
16. ¿Qué se puede hacer en una Subclase?
En las subclases podemos heredar los miembros tal como están, reemplazarlos, ocultarlos o complementarlos
con nuevos miembros:
Los campos heredados se pueden usar directamente, al igual que cualquier otro campo.
Podemos declarar nuevos campos en la subclase que no están en la superclase.
Los métodos heredados se pueden usar directamente tal como son.
Podemos escribir un nuevo método de instancia en la subclase que tenga la misma firma que el de la
superclase, anulándolo (como en el ejemplo anterior, el método toString() se reemplaza).
Se puede escribir un nuevo método estático en la subclase que tiene la misma firma que el de la
superclase, escondiéndolo así.
Podemos declarar nuevos métodos en la subclase que no están en la superclase.
Podemos escribir un constructor de subclase que invoca el constructor de la superclase, ya sea
implícitamente o mediante la palabra clave super.
17. Redefinición de métodos heredados.
Una clase puede redefinir algunos de los métodos que ha heredado de su clase base. En tal
caso, el nuevo método (especializado) sustituye al heredado. Este procedimiento también es
conocido como de sobrescritura de métodos.
En cualquier caso, aunque un método sea sobrescrito o redefinido, aún es posible acceder a él
a través de la referencia super, aunque sólo se podrá acceder a métodos de la clase padre y no
a métodos de clases superiores en la jerarquía de herencia.
Los métodos redefinidos pueden ampliar su accesibilidad con respecto a la que ofrezca el
método original de la superclase, pero nunca restringirla. Por ejemplo, si un método es
declarado como protected o de paquete en la clase base, podría ser redefinido como public en
una clase derivada.
Los métodos estáticos o de clase no pueden ser
sobrescritos. Los originales de la clase base
permanecen inalterables a través de toda la jerarquía
de herencia.
18. En el ejemplo de la clase Alumno, podrían redefinirse algunos de los métodos heredados. Por ejemplo, imagina
que el método getApellidos devuelva la cadena "Alumno:" junto con los apellidos del alumno. En tal caso habría
que rescribir ese método para realizara esa modificación:
public String getApellidos() {
return "Alumno: " + apellidos;
}
Cuando sobrescribas un método heredado en Java puedes incluir la anotación @Override. Esto indicará al
compilador que tu intención es sobrescribir el método de la clase padre. De este modo, si te equivocas (por
ejemplo, al escribir el nombre del método) y no lo estás realmente sobrescribiendo, el compilador producirá un
error y así podrás darte cuenta del fallo. En cualquier caso, no es necesario indicar @Override, pero puede
resultar de ayuda a la hora de localizar este tipo de errores (crees que has sobrescrito un método heredado y
al confundirte en una letra estás realmente creando un nuevo método diferente). En el caso del ejemplo
anterior quedaría:
@Override
public String getApellidos()