El proceso por el cual una clase adquiere las propiedades (miembros de datos) y características (métodos) de otra clase se llama herencia. El propósito de la herencia es proporcionar reutilización de código para que una clase solo tenga que escribir características únicas y el resto de las propiedades y funciones comunes puedan ser extendidas por otra clase.
Clase infantil:
La clase que amplía la funcionalidad de otra clase se conoce como clase secundaria, subclase o clase derivada.
Clase para padres:
La clase cuyas propiedades y funcionalidad son utilizadas (heredadas) por otra clase se conoce como clase principal, superclase o clase base.
La herencia es un proceso de definición de una nueva clase basada en una clase existente mediante la extensión de sus miembros y métodos de datos comunes.
La herencia nos permite reutilizar código, mejorar la reutilización en su aplicación java.
Nota: el más grande ventaja de la herencia es que el código que ya está presente en la clase base no necesita ser reescrito en la clase secundaria.
Esto significa que los miembros de datos (variables de instancia) y los métodos de la clase principal se pueden usar en la clase secundaria, como.
Si tiene problemas para comprender qué son la clase y el objeto, consulte la guía que compartí sobre Programación orientada a objetos: conceptos de POO
Volvamos al tema:
Sintaxis: herencia en Java
Para heredar una clase, usamos la palabra clave extensions. Aquí, la clase XYZ es la clase secundaria y la clase ABC es la clase principal. La clase XYZ hereda las propiedades y métodos de la clase ABC.
class XYZ extends ABC { }
Ejemplo de herencia
En este ejemplo, tenemos una clase base Teacher
y una subclase PhysicsTeacher
. De la lección PhysicsTeacher
extiende la designación y las propiedades de la universidad y el método work () de la clase base, no es necesario declarar estas propiedades y el método en la subclase.
Aquí tenemos collegeName, designación y trabajo () que son comunes a todos los maestros, por lo que los hemos declarado en la clase base, por lo tanto las clases secundarias MathTeacher
, MusicTeacher
es PhysicsTeacher
no es necesario escribir este código y se puede utilizar directamente desde la clase base.
class Teacher { String designation = "Teacher"; String collegeName = "Beginnersbook"; void does(){ System.out.println("Teaching"); } } public class PhysicsTeacher extends Teacher{ String mainSubject = "Physics"; public static void main(String args[]){ PhysicsTeacher obj = new PhysicsTeacher(); System.out.println(obj.collegeName); System.out.println(obj.designation); System.out.println(obj.mainSubject); obj.does(); } }
Producción:
Beginnersbook Teacher Physics Teaching
Basado en el ejemplo anterior, podemos decir
PhysicsTeacher
ES UNTeacher
. Esto significa que una clase secundaria tiene una relación IS-A con la clase principal. Este es el legado conocido como Relación IS-A entre clase padre e hijo
Nota:
La clase derivada hereda todos los miembros y métodos declarados como públicos o protegidos. Si los miembros o métodos de la superclase se declaran privados, la clase derivada no puede usarlos directamente. Solo se puede acceder a los miembros privados en su propia clase. Solo se puede acceder a estos miembros privados utilizando métodos getter y setter de superclase públicos o protegidos, como se muestra en el siguiente ejemplo.
class Teacher { private String designation = "Teacher"; private String collegeName = "Beginnersbook"; public String getDesignation() { return designation; } protected void setDesignation(String designation) { this.designation = designation; } protected String getCollegeName() { return collegeName; } protected void setCollegeName(String collegeName) { this.collegeName = collegeName; } void does(){ System.out.println("Teaching"); } } public class JavaExample extends Teacher{ String mainSubject = "Physics"; public static void main(String args[]){ JavaExample obj = new JavaExample(); /* Note: we are not accessing the data members * directly we are using public getter method * to access the private members of parent class */ System.out.println(obj.getCollegeName()); System.out.println(obj.getDesignation()); System.out.println(obj.mainSubject); obj.does(); } }
La salida es:
Beginnersbook Teacher Physics Teaching
El punto importante a tener en cuenta en el ejemplo anterior es que la clase secundaria puede acceder a los miembros privados de la clase principal a través de métodos protegidos de la clase principal. Cuando creamos una variable de instancia (miembro de datos) o un método protegido, esto significa que solo son accesibles en la propia clase y en la clase secundaria. Estos elementos públicos, protegidos, privados, etc. Todos son especificadores de acceso y los discutiremos en los próximos tutoriales.
Tipos de herencia
Para conocer los tipos de herencia en detalle, consulte: Tipos de herencia en Java.
Herencia única: Se refiere a una relación de clase secundaria y primaria en la que una clase extiende a la otra clase.
Herencia multinivel: se refiere a una relación de clase secundaria y primaria en la que una clase extiende la clase secundaria. Por ejemplo, la clase C extiende la clase B y la clase B extiende la clase A.
Herencia jerárquica: se refiere a una relación de clase secundaria y primaria en la que más de una clase extiende la misma clase. Por ejemplo, las clases B, C y D se extienden a la misma clase A.
Herencia múltiple: se refiere al concepto de una clase que se extiende a más de una clase, lo que significa que una clase secundaria tiene dos clases principales. Por ejemplo, la clase C extiende las clases A y B. Java no admite herencia múltiple, lea más aquí.
Herencia híbrida: combina varios tipos de herencia en un programa. Por ejemplo, la clase A y B amplía la clase C y otra clase D amplía la clase A, por lo que este es un ejemplo de herencia híbrida porque es una combinación de herencia única y jerárquica.
Constructores y herencia
el constructor de subclase se invoca cuando creamos el objeto de subclase, de forma predeterminada invoca el constructor predeterminado de superclase. Por tanto, en herencia, los objetos se construyen de arriba a abajo. El constructor de superclase se puede llamar explícitamente usando la palabra clave super, pero debería ser la primera declaración en un constructor. La palabra clave super se refiere a la superclase, inmediatamente arriba de la clase que llama en la jerarquía. No se permite que varias súper palabras clave accedan a una clase de ancestro que no sea el padre directo.
class ParentClass{ //Parent class constructor ParentClass(){ System.out.println("Constructor of Parent"); } } class JavaExample extends ParentClass{ JavaExample(){ /* It by default invokes the constructor of parent class * You can use super() to call the constructor of parent. * It should be the first statement in the child class * constructor, you can also call the parameterized constructor * of parent class by using super like this: super(10), now * this will invoke the parameterized constructor of int arg */ System.out.println("Constructor of Child"); } public static void main(String args[]){ //Creating the object of child class new JavaExample(); } }
Producción:
Constructor of Parent Constructor of Child
Herencia y sustitución de métodos
Cuando declaramos el mismo método en la clase secundaria que ya está presente en la clase principal, esto se denomina anulación de método. En este caso, cuando llamamos al método desde el objeto de la clase secundaria, se llama a la versión de la clase secundaria del método. Sin embargo, podemos llamar al método de la clase padre usando la palabra clave super como he mostrado en el siguiente ejemplo:
class ParentClass{ //Parent class constructor ParentClass(){ System.out.println("Constructor of Parent"); } void disp(){ System.out.println("Parent Method"); } } class JavaExample extends ParentClass{ JavaExample(){ System.out.println("Constructor of Child"); } void disp(){ System.out.println("Child Method"); //Calling the disp() method of parent class super.disp(); } public static void main(String args[]){ //Creating the object of child class JavaExample obj = new JavaExample(); obj.disp(); } }
La salida es:
Constructor of Parent Constructor of Child Child Method Parent Method