Está en la página 1de 11

HERENCIA

La herencia es una propiedad que permite la declaración de nuevas clases a partir de otras ya
existentes. Esto proporciona una de las ventajas principales de la Programación Orientada a
Objetos: la reutilización de código previamente desarrollado ya que permite a una clase más
específica incorporar la estructura y comportamiento de una clase más general.

Cuando una clase B se construye a partir de otra A mediante la herencia, la clase B hereda
todos los atributos, métodos y clases internas de la clase A. Además la clase B puede redefinir
los componentes heredados y añadir atributos, métodos y clases internas específicas.

Para indicar que la clase B (clase descendiente, derivada, hija o subclase) hereda de la clase A
(clase ascendiente, heredada, padre, base o superclase) se emplea la palabra
reservada extends en la cabecera de la declaración de la clase hija. La sintaxis es la siguiente:

public class ClaseB extends ClaseA {


// Declaracion de atributos y metodos especificos de ClaseB

// y/o redeclaracion de componentes heredados

La claseB hereda de la claseA. Con lo que es hija o descendiente de la claseA.

Ejemplo de esquema de herencia.

En ese esquema se puede apreciar como los todoterrenos son coches, que a su vez son
automóviles y a su vez son vehículos. Con lo que los todoterrenos adquieren las características
heredadas de todas las clases previas.

1
En Java cada clase sólo puede heredar de una superclase. Eso significa que sólo hay una
clase padre. Este tema fue controvertido ya que lenguajes como C++ admiten herencia
múltiple que significa que una clase puede tener varias clases padre de las que heredaría sus
características.
La decisión de no permitir este tipo de herencia se debe a que a la hora de determinar la clase
de un objeto habría problemas ya que un objeto se podría considerar perteneciente a varias
clases al instanciar.
Las interfaces permiten utilizar cuestiones relativas a la herencia múltiple como se verá más
adelante.

Ejemplo 1:

//primer archivo

public class Vehiculo {


public int velocidad;
public int ruedas;

public void parar() {


velocidad = 0;
}
public void acelerar(int kmh) {
velocidad += kmh;
}
}

//segundo archivo
public class Coche extends Vehiculo {
public int ruedas=4;
public int gasolina;

public void repostar(int litros) {


gasolina+=litros;
}
}

//tercer archivo
public class PruebaCoche {

public static void main(String[] args) {

Coche coche1=new Coche();


coche1.acelerar(80); //Método heredado
coche1.repostar(12); //Método nuevo, no heredado
}
}

2
Sobrescribir o anular métodos de la superclase.

Las subclases heredan los métodos de las superclases. Pero es más, también los pueden
sobrecargar para proporcionar una versión de un determinado método adaptado a las
necesidades de la nueva clase.

Por último, si una subclase define un método con el mismo nombre, tipo y argumentos que un
método de la superclase, se dice entonces que se sobrescribe o anula el método de la
superclase.

public class Coche extends Vehiculo {


public double gasolina;

public void acelerar(double kmh) {


super.acelerar(kmh)
gasolina=0.9;
}
}

En el ejemplo anterior, la llamada super.acelerar(kmh) llama al método acelerar de la clase


Vehículo (el cual acelerará la marcha). Es necesario redefinir el método acelerar en la clase
coche ya que aunque la velocidad varía igual que en la superclase, hay que tener en cuenta el
consumo de gasolina. Por ello invocamos al método acelerar de la clase padre (que no está
oculto gracias a super).

Ejemplo:
public class Vehiculo{
double velocidad;
public Vehiculo(double v){
velocidad=v;
}
}
public class Coche extends Vehiculo{
double gasolina;
public Coche(double v, double g){ //constructor de coche
super(v); //Llama al constructor de la clase vehiculo
gasolina=g
}
}

Se puede incluso llamar a un constructor de una superclase, usando la sentencia super.

3
HERENCIA Y CONSTRUCTORES

La subclase necesita normalmente que se ejecute el constructor de la superclase antes que


su propio constructor para inicializar las variables de instancia heredadas. La solución consiste
en utilizar la palabra reservada super seguida entre paréntesis de los parámetros
correspondiente en el cuerpo del constructor de la subclase. Es decir, incluir la siguiente
sentencia como primera línea de código:

super(argumentos opcionales);

public Coche(double v, double g){ //constructor de coche


super(v); //Llama al constructor de la clase vehiculo
gasolina=g
}

constructores
Los constructores no se heredan de la clase padre a las clases hijas. Pero sí se puede
invocar al constructor de la clase padre.

De hecho por defecto aunque haya o no haya constructor se hace una invocación al
constructor por defecto de la clase padre. Ejemplo:

public classA {
protected int valor;

public A(){ //constructor sin parámetros


valor=2;
}
public void escribir(){
System.out.println(valor);

}
}

La clase A simplemente tiene una propiedad (heredable) que se coloca con el valor 2 en el
constructor por defecto.

public classB extends A {


public void escribir(){
System.out.println(valor*2);
}
}

4
La clase B es hija de A. Ha redefinido el método escribir y además no tiene constructor. Pero
puede utilizar la propiedad valor que procede de la clase A. Así este código:

public static void main(String[] args) {


A objA=new A(); //objeto de la clase A
B objB=new B(); //objeto de la clase B
objA.escribir(); //escribe 2
objB.escribir(); //escribe 4
}

Sin embargo si la clase A no tuviera constructor sin parámetros (por defecto):

Solución: llamar al constructor de la clase A

5
Constructores en las clases A y B

public class A {
protected int valor;

public A(int v){


valor=v;
}
public void escribir(){
System.out.println(valor);
}
}

public class B extends A {


char caracter;

public B(int v){ //constructor


super(v);
}
public B(int v, char c){ //constructor
this(v);
caracter=c;
}
public void escribir(){
System.out.println(valor*2+" "+caracter);
}
}

El uso de super y this no puede ser simultáneo puesto que ambas tienen que ser la
primera instrucción. Lo que significa que hay que elegir entre ambas.

REDEFINICIÓN DE ELEMENTOS HEREDADOS

Como se ha comentado anteriormente la clase descendiente puede añadir sus propios


atributos y métodos pero también puede sustituir u ocultar los heredados. En concreto:

 Se puede declarar un nuevo atributo con el mismo identificador que uno heredado,
quedando este atributo oculto. Esta técnica no es recomendable.

 Se puede declarar un nuevo método de instancia con la misma cabecera que el de la clase
padre, lo que supone su sobreescritura. Por lo tanto, la sobreescritura o redefinición

6
consiste en que métodos adicionales declarados en la clase hija con el mismo nombre, tipo
de dato devuelto y número y tipo de parámetros sustituyen a los heredados.

 Se puede declarar un nuevo método de clase con la misma cabecera que el de la clase
padre, lo que hace que éste quede oculto. Por lo tanto, los métodos de clase o estáticos
(declarados como static) no pueden ser redefinidos.

 Un método declarado con el modificador final tampoco puede ser redefinido por una clase
hija.

 Se puede declarar un constructor de la subclase que llame al de la superclase de forma


implícita o de mediante la palabra reservada super.

 En general puede accederse a los métodos de la clase padre que han sido redefinidos
empleando la palabra reservada super delante del identificador del método. Este
mecanismo sólo permite acceder al método perteneciente a la clase en el nivel
inmediatamente superior de la jerarquía de clases.

Ejemplo 2: (para hacer en casa)

Por ejemplo, a partir de la clase Precio:

/**


* Ejemplo de declaracion de la clase Precio*/

public class Precio {


// Variable de instancia

public double euros;


// Metodos publicos

public double da() {

return this.euros;

public void pone(double x) {

this.euros = x;

7
se construye la clase Producto como hija de la clase Precio de la siguiente forma:

/**


* Ejemplo de declaracion de la clase Producto

* clase producto desciende de Precio

*/

public class Producto extends Precio {

// Variable de instancia


public int codigo;


// Metodos publicos

public int daCodigo() {

return this.codigo;


public void asignaCodigo(int x) {

this.codigo=x;

public void asignaProducto(int cod, double p) {

this.asignaCodigo(cod);


this.pone(p);


public String toString() {

return "Codigo: " + codigo + " ; precio: " + euros + " euros";

8
La clase PruebaClaseProducto trabaja con dos instancias de la clase Producto:

/**

* Demostracion de la clase Producto

*/

public class PruebaClaseProducto {


public static void main (String [] args){

Producto p = new Producto();

p.asignaProducto(200201, 15.8);

System.out.println(p.toString());

Producto q = new Producto();

q.asignaCodigo(200202);

q.pone(34.3);

System.out.println(q.toString());

9
Ejercicio 1. Enunciado:

La clase base es la clase Empleado. Esta clase contiene:


Un atributo privado nombre de tipo String que heredan el resto de clases.
Un constructor por defecto.
Un constructor con parámetros que inicializa el nombre con el String que recibe.
Método set y get para el atributo nombre.
Un método toString() que devuelve el String: "Empleado " + nombre.

El resto de clases solo deben sobrescribir el método toString() en cada una de ellas
y declarar el constructor adecuado de forma que cuando la ejecución de las
siguientes instrucciones:

10
11

También podría gustarte