Herencia en Java


Concepto de herencia

La herencia es una piedra angular de la tecnología de programación orientada a objetos de Java, porque permite crear clases jerárquicas por niveles.

La herencia consiste en que la subclase hereda las características y comportamientos de la clase padre, de modo que los objetos (instancias) de la subclase tienen los campos de instancia y métodos de la clase padre, o la subclase hereda métodos de la clase padre, haciendo que la subclase tenga los mismos comportamientos que la clase padre.

Herencia en la vida cotidiana:

Los conejos y las ovejas pertenecen a la clase de los herbívoros; los leones y los leopardos pertenecen a la clase de los carnívoros.

Los herbívoros y los carnívoros, a su vez, pertenecen a la clase de los animales.

Por lo tanto, la relación que debe cumplir la herencia es: is-a (es-un), la clase padre es más general y la subclase es más específica.

Aunque los herbívoros y los carnívoros pertenecen a los animales, sus atributos y comportamientos difieren, por lo que la subclase poseerá las características generales de la clase padre y también sus propias características.

Formato de herencia de clases

En Java, mediante la palabra clave extends se puede declarar que una clase hereda de otra clase; la forma general es la siguiente:

Formato de herencia de clases

classClase padre{ } classSubclaseextendsClase padre{ }

Por qué se necesita la herencia

A continuación, explicaremos esta necesidad mediante un ejemplo.

Desarrolle una clase de animales, donde los animales son el pingüino y el ratón, con los siguientes requisitos:

  • Pingüino: atributos (nombre, id), métodos (comer, dormir, presentarse)
  • Ratón: atributos (nombre, id), métodos (comer, dormir, presentarse)

Clase Pingüino:

public class Penguin { private String name; private int id; public Penguin(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"Comiendo"); } public void sleep(){ System.out.println(name+"Durmiendo"); } public void introduction() { System.out.println("¡Hola a todos! Soy" + id + "号" + name + "."); } }

Clase Ratón:

public class Mouse { private String name; private int id; public Mouse(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"Comiendo"); } public void sleep(){ System.out.println(name+"Durmiendo"); } public void introduction() { System.out.println("¡Hola a todos! Soy" + id + "号" + name + "."); } }

Como se puede observar en estos dos fragmentos de código, hay código repetido, lo que hace que el código sea extenso y redundante, y además sea difícil de mantener (principalmente porque cuando se necesita modificar más adelante, hay que cambiar mucho código y es fácil cometer errores). Para resolver fundamentalmente el problema de estos dos fragmentos de código, se necesita la herencia, extrayendo las partes comunes de ambos fragmentos para formar una clase padre:

Clase padre común:

public class Animal { private String name; private int id; public Animal(String myName, int myid) { name = myName; id = myid; } public void eat(){ System.out.println(name+"Comiendo"); } public void sleep(){ System.out.println(name+"Durmiendo"); } public void introduction() { System.out.println("¡Hola a todos! Soy" + id + "号" + name + "."); } }

Esta clase Animal puede servir como clase padre. Después de que las clases Pingüino y Ratón hereden de ella, tendrán los atributos y métodos de la clase padre, la subclase ya no tendrá código repetido, el mantenimiento mejorará, el código será más conciso y se aumentará la reutilización del código (la reutilización significa principalmente que se puede usar varias veces sin tener que escribir el mismo código repetidamente). Código después de la herencia:

Clase Pingüino:

public class Penguin extends Animal { public Penguin(String myName, int myid) { super(myName, myid); } }

Clase Ratón:

public class Mouse extends Animal { public Mouse(String myName, int myid) { super(myName, myid); } }

Tipos de herencia

Cabe señalar que Java no admite la herencia múltiple, pero sí admite la herencia multinivel.


Características de la herencia

  • La subclase posee los atributos y métodos no privados de la clase padre.

  • La subclase puede tener sus propios atributos y métodos, es decir, la subclase puede extender la clase padre.

  • La subclase puede implementar los métodos de la clase padre a su manera.

  • La herencia en Java es herencia única, pero puede ser multinivel. La herencia única significa que una subclase solo puede heredar de una clase padre. La herencia multinivel significa, por ejemplo, que la clase B hereda de la clase A y la clase C hereda de la clase B, por lo que en la relación, la clase B es la clase padre de la clase C, y la clase A es la clase padre de la clase B. Esta es una característica que distingue la herencia de Java de la herencia de C++.

  • Aumenta el acoplamiento entre clases (una desventaja de la herencia: un acoplamiento alto hace que la conexión entre el código sea más estrecha y la independencia del código sea menor).


Palabras clave de la herencia

La herencia se puede implementar con las palabras clave extends e implements, y todas las clases heredan de java.lang.Object. Cuando una clase no utiliza ninguna de estas dos palabras clave para heredar, hereda Object por defecto (esta clase está enjava.langel paquete, por lo que no es necesarioimportla clase ancestro.

La palabra clave extends

En Java, la herencia de clases es única, es decir, una subclase solo puede tener una clase padre, por lo que extends solo puede heredar de una clase.

La palabra clave extends

public class Animal { private String name; private int id; public Animal(String myName, int myid) { //Inicializar el valor de los atributos } public void eat() { //Implementación concreta del método comer } public void sleep() { //Implementación concreta del método dormir } } public class Penguin extends Animal{ }

La palabra clave implements

El uso de la palabra clave implements puede hacer que Java tenga herencia múltiple de manera indirecta. Su ámbito de uso es cuando una clase hereda interfaces; puede heredar varias interfaces simultáneamente (las interfaces se separan con comas).

La palabra clave implements

public interface A { public void eat(); public void sleep(); } public interface B { public void show(); } public class C implements A,B { }

Las palabras clave super y this

Palabra clave super:Podemos acceder a los miembros de la clase padre mediante la palabra clave super, que se utiliza para hacer referencia a la clase padre del objeto actual.

Palabra clave this:Es una referencia que apunta a sí mismo, hace referencia al objeto actual, es decir, a la instancia del objeto al que pertenecen el método o constructor en el que se encuentra.

Ejemplo

class Animal { void eat() { System.out.println("animal : eat"); } } class Dog extends Animal { void eat() { System.out.println("dog : eat"); } void eatTest() { this.eat(); //this llama a su propio método super.eat(); //super llama al método de la clase padre } } public class Test { public static void main(String[] args) { Animal a = new Animal(); a.eat(); Dog d = new Dog(); d.eatTest(); } }

El resultado de salida es:

animal : eat
dog : eat
animal : eat

La palabra clave final

final se puede utilizar para modificar variables (incluidos atributos de clase, atributos de objeto, variables locales y parámetros formales), métodos (incluidos métodos de clase y métodos de objeto) y clases.

El significado de final es 'definitivo'.

Declarar una clase con la palabra clave final define la clase como una clase final que no puede ser heredada, o se usa para modificar un método, y ese método no puede ser reescrito por subclases:

  • Declarar clase:

    final class 类名 {//类体}
  • Declarar método:

    修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

Nota:En una clase definida como final, sus atributos y métodos no son final.


Constructor

La subclase no hereda el constructor de la clase padre (método constructor o función constructora), solo lo invoca (implícita o explícitamente). Si el constructor de la clase padre tiene parámetros, entonces se debe invocar explícitamente en el constructor de la subclase mediantesuperla palabra clave para invocar al constructor de la clase padre, junto con la lista de parámetros adecuada.

Si el constructor de la clase padre no tiene parámetros, entonces no es necesario usar en el constructor de la subclasesuperla palabra clave para invocar al constructor de la clase padre; el sistema invocará automáticamente el constructor sin parámetros de la clase padre.

Ejemplo

class SuperClass { private int n; //Constructor sin parámetros public SuperClass() { System.out.println("SuperClass()"); } //Constructor con parámetros public SuperClass(int n) { System.out.println("SuperClass(int n)"); this.n = n; } } //La clase SubClass hereda class SubClass extends SuperClass { private int n; //Constructor sin parámetros: llama automáticamente al constructor sin parámetros de la clase padre public SubClass() { System.out.println("SubClass()"); } //Constructor con parámetros: llama al constructor con parámetros de la clase padre public SubClass(int n) { super(300); System.out.println("SubClass(int n): " + n); this.n = n; } } //La clase SubClass2 hereda class SubClass2 extends SuperClass { private int n; //Constructor sin parámetros: llama al constructor con parámetros de la clase padre public SubClass2() { super(300); System.out.println("SubClass2()"); } //Constructor con parámetros: llama automáticamente al constructor sin parámetros de la clase padre public SubClass2(int n) { System.out.println("SubClass2(int n): " + n); this.n = n; } } public class TestSuperSub { public static void main(String[] args) { System.out.println("------Herencia de la clase SubClass------"); SubClass sc1 = new SubClass(); SubClass sc2 = new SubClass(100); System.out.println("------Herencia de la clase SubClass2------"); SubClass2 sc3 = new SubClass2(); SubClass2 sc4 = new SubClass2(200); } }

El resultado de salida es:

------SubClass 类继承------
SuperClass()
SubClass()
SuperClass(int n)
SubClass(int n): 100
------SubClass2 类继承------
SuperClass(int n)
SubClass2()
SuperClass()
SubClass2(int n): 200
Otras extensiones