Buenas,
En este tema volvemos a la POO viendo una característica muy importante de esta; la herencia.
Teoria
- La herencia permite que una clase herede (tenga como suyos) los métodos y atributos de otra.
- Las herencias son jerárquicas; Puede haber una cadena de herencias, y cuanto mas “debajo” este la clase mas elementos heredara.
- Una clase solo puede heredar de otra. En Java no hay herencia múltiple como tal, aunque, si que existe una forma de emularlo; con
interface
la cual no creo que lleguemos a ver en este curso. - De hecho todas las clases que creamos y que ya están definidas, heredan de la clase
object
, lo cual nos permite usar métodos comotoString()
,equals()
,getClass()
, … - Podemos definir la relación (de herencia) entre dos clases como superclase (la clase “Padre/madre”) y la subclase (la clase hijo/a).
- Por defecto, las clases pueden ser superclase, es decir, se puede heredar de ellas. Pero también es posible bloquear esta característica declarando la clase como
final
.
Ejemplo de esto es la claseString
, de la cual no podemos heredar.
¿Para que nos sirve la herencia?
Si necesitamos crear una clase similar a otra, pero con algún cambio, o si queremos crear varias clases parecidas, que seguramente compartan algunos atributos y métodos, pero, necesariamente tienen que ser diferentes, podemos crear una clase que recoja, por así decirlo, lo básico de todas las clases. Esto nos permite reutilizar y ordenar adecuadamente el código así como integrar funciones ya escritas en nuestro programa de manera eficiente.
Sintaxis
Simplemente debemos añadir la clausula extends [clase]
al final de la declaración de una clase.
Sintaxis
public class [nombre] extends [superclase]
{
// Definición de la clase.
}
Ejemplo
public class Contable extends Trabajador
{
// Definición de la clase.
}
Override o sobrescribir
Hemos dicho que la una clase heredar de otra, la subclase pasa a tener los mismos métodos y atributos que la superclase mas los suyos propios.
¿Pero que pasa si queremos que el bloque de código de x método sea diferente?
En ese caso podemos sobrescribir el método original:
No hay que hacer nada complicado, solo hay que declarar el método igual que el de la superclase y definirlo como se quiera.
Esto automáticamente remplazara el método de la superclase cuando se llame desde la subclase (o un objeto suyo) así como de las clases que hereden de la subclase.
Ejemplo
El método toString siempre es interesante personalizarlo:
@Override
public String toString()
{
return "Oficinista de la oficina: " + numero_oficina + ", con el cargo de: " + cargo + ".";
}
la etiqueta @Override
no es necesaria, pero no esta de mas. Eclipse la pone automáticamente.
super()
Cuando la superclase cuenta con uno o mas métodos constructores, debemos llamarlo en el constructor de la subclase.
Esto se hace mediante el método super()
y es necesario porque cuando se instancia un objeto, también se instancia la superclase del mismo.
Ejemplo
public class Trabajador
{
public Trabajador (String n)
{
}
public class Contable extends Trabajador
{
// Definición de la clase.
}
Por ejemplo,
Queremos hacer varias clases para representar figuras; Rectángulos , Triángulos, Círculos… Todas tendrán sus diferencias; Los rectángulos se medirán con dos lados, los círculos con el ratio… Pero todas compartirán atributos como el color y métodos como devolver el perímetro, el área… Estos elementos comunes pueden ser parte de la clase Figura
de la cual heredaran el resto.
Figura.java
public class Figura
{
public String color;
public Figura (String c)
{
color = c;
}
public String getColor()
{
return color;
}
public double getArea()
{
return 0;
}
public double getPerimetro()
{
return 0;
}
public String toString()
{
return "Color: " + color + ".";
}
}
En vez de devolver 0, podríamos usar abstracción, pero no creo que nos de para verlo en este curso básico.
Circulo.java
public class Circulo extends Figura
{
private double radio;
public Circulo(String c, double r)
{
super(c);
radio = r;
}
@Override
public double getArea()
{
return Math.PI * Math.pow(radio,2); // π x radio². Ya veremos la clase Math mas adelante.
}
@Override
public double getPerimetro()
{
return 2 * Math.PI * radio; // 2 x π x radio. Ya veremos la clase Math mas adelante.
}
@Override
public String toString()
{
return "Color: " + color + ", radio: " + radio + ".";
}
}
Rectangulo.java
public class Rectangulo extends Figura
{
private double altura, base;
public Rectangulo(String c, double altura, double base)
{
super(c);
this.altura = altura;
this.base = base;
}
@Override
public double getArea()
{
return altura * base;
}
@Override
public double getPerimetro()
{
return 2 * (altura + base);
}
@Override
public String toString()
{
return "Color: " + color + ", altura: " + altura + ", base: " + base +".";
}
}
Triangulo.java
public class Triangulo extends Figura
{
private double altura, a, b, c;
String color = "Azul.";
public Triangulo(String color, double altura, double a, double b, double c)
{
super(color);
this.altura = altura;
this.a = a;
this.b = b;
this.c = c;
}
@Override
public double getArea()
{
return (a * altura) / 2;
}
@Override
public double getPerimetro()
{
return a + b + c;
}
@Override
public String toString()
{
return "Color: " + color + ", altura: " + altura + ", lado 'a': " + a
+ ", lado 'b': " + b + ", lado 'c': " + c +".";
}
}
Aunque ha sido una explicación exprés, creo que la base se entiende. Si queda alguna duda o alguien quiere aportar o citar información extra relacionada, le animo a hacerlo.
En el siguiente tema veremos enum
como una estructura de POO en Java.
- Indice.
- → Siguiente: Curso básico de Java - #18 - POO: Enum
- ← Anterior: Curso básico de Java - #16 - Clases fundamentales: String