Bienvenidos sean a este post, hoy veremos otra de las patas fundamentales de la mesa que representa a la programacion orientada a objetos.
Cuando hablamos de herencia en programacion siempre hablamos de la capacidad de poder acceder a los elementos de una clase padre desde una clase hija, y sin saberlo estuvimos usandolo desde el principio porque la herencia en Java se hace a traves de la palabra extends, veamos una linea de ejemplo:
public class MainActivity extends Activity {
En este caso nuestra clase MainActivity tendra accceso a todos los elementos (metodos y propiedades) que posea la clase Activity, para entender mejor el concepto analicemos el siguiente ejemplo:
public class Animal {
public int edad;
public float altura;
public String nombre;
protected String Hablar(){
return "El Animal esta hablando";
}
}
Esta va a ser nuestra clase maestra o padre donde sera la base para nuestros futuras clases herederas, para este caso elegimos una clase muy generica como es Animal, ya veremos porque, en este caso la haremos facil y setearemos tres variables de tipo public las cuales almacenaran la edad, la altura y el nombre, despues tendremos un metodo llamado Hablar que devolvera un mensaje indicando que el animal esta hablando, con esto concluimos nuestra clase maestra pasemos a la siguiente:
package org.example.animal;
public class Perro extends Animal {
public Perro(int e, float a, String n){
this.edad = e;
this.altura = a;
this.nombre = n;
}
@Override
protected String Hablar(){
return "Guau!!!";
}
}
En este caso vamos a tener una clase llamada Perro la cual extendera o mejor dicho sera heredera de Animal por medio del extends, nuestro primer metodo sera el constructor de la clase, la cual para este caso le diremos que reciba tres valores para iniciar las variables de la clase padre (Animal), lo unico que usamos para este codigo fue el this para cada variable y esto se encargara de informar que cada valor sera asignado unicamente al objeto que se creo de Perro y no de Animal.
Luego tendremos una reescritura (Override) del metodo Hablar, en la cual modificaremos el contenido del bloque para que tome otra conducta, por ejemplo en la clase Animal nos informa que este esta hablando porque no sabemos cual animal es pero en cambio como en la clase Perro si sabemos quien es podemos hacer que devuelve el sonido del animal correspondiente, lo mismo aplicaria si hubiera a otros animales como gatos, caballos, cerdos, etc, con este ejemplo pudimos ver como no solamente recibimos los elementos de la clase padre sino tambien podemos modificarlos (en el caso de los metodos) pero nosotros tambien podemos tener nuestros propios metodos o variables por ejemplo modifiquemos a la clase Perro de la siguiente manera:
package org.example.animal;
public class Perro extends Animal {
private int peso;
public Perro(int e, float a, String n, int p){
this.edad = e;
this.altura = a;
this.nombre = n;
peso = p;
}
@Override
protected String Hablar(){
return "Guau!!!";
}
public String Caminar(){
return "El perro esta caminando";
}
}
En este ejemplo agregamos una nueva variable llamada peso la cual sera exclusiva de Perro y Animal no tendra acceso, vean como cambiamos el constructor porque tambien necesitamos iniciar a peso y despues agregamos un nuevo metodo el cual se encarga de indicar que el perro esta caminando, como dijimos anteriormente esta nueva variable y nuevo metodo no son accedidos por Animal porque la herencia es siempre hacia abajo y nunca para arriba, en cambio si hubiera otra clase heredera de Perro no solamente hereda de su clase maestra sino tambien de la maestra de esta clase maestra, esto es una version muy resumida de lo que es herencia para entender mejor este concepto vamos a crear un nuevo proyecto con las siguientes caracteristicas:
- Dispositivos: Phone and Tablet
- Actividad: Empty Activity
- Nombre: Herencias
- Nombre de paquete: org.example.herencias
- API Minimo: API 14 (Android 4.0)
Una vez creado nuestro proyecto procederemos a crear una nueva clase de Java para ello hacer click con el boton derecho sobre el contenedor de las clases Java y seleccionaremos New -> Java Class, en el nuevo cuadro completaremos estos campos:
- Nombre: NaveAlien
- Tipo: Class
Una vez completado los valores presionamos Enter para generarla y pasemos a modificar el codigo generado automaticamente de la siguiente manera:
NaveAlien.java
package org.example.herencias;
import android.util.Log;
public abstract class NaveAlien {
private static int numNaves;
private int fuerzaEscudo;
public String nombreNave;
public NaveAlien(int fuerza) {
numNaves++;
this.setFuerzaEscudo(fuerza);
}
public abstract void disparaArma();
public static int getNumNaves() {
return numNaves;
}
private void setFuerzaEscudo(int f) {
this.fuerzaEscudo = f;
}
public int getFuerzaEscudo() {
return this.fuerzaEscudo;
}
public void impactoDetectado() {
fuerzaEscudo -= 25;
Log.i("Ahi vienen", "Bam!!");
if (fuerzaEscudo == 0) {
destruirNave();
}
}
private void destruirNave() {
numNaves--;
Log.i("QEPD", this.nombreNave + " fue destruida");
}
}
Esta clase es muy similar a la vista en el post anterior pero con unas sutiles diferencias, la primera es esta linea:
public abstract class NaveAlien {
En una muy breve explicacion, el modificador abstract nos garantiza que cualquier clase heredera de esta pueda implementar su propia version de un metodo que veremos luego, la siguiente modificacion es en nuestro constructor donde ahora recibira un valor para el campo de fuerza y lo asignara a la nave, por ultimo tenemos este metodo:
public abstract void disparaArma();
De esta hablaremos mas adelante pero si observan no solamente tiene la palabra abstract, lo cual nos obliga a que nuestra clase sea abstract sino que ademas no tiene bloque, esto es debido a que es un «prototipo» y en lugar de definir una accion nos da el molde para que nuestras clases hijas definan el suyo de manera propia sin inconvenientes, el resto de las variables y metodos son exactamente a lo visto en el post anterior, para nuestro siguiente paso crearemos otra clase de Java de la misma forma que antes pero con los siguientes datos:
- Nombre: Bombardero
- Tipo: Class
Al igual que antes presionamos Enter para crearlo, una vez generada la nueva clase la reemplazaremos con el siguiente codigo:
Bombardero.java
package org.example.herencias;
import android.util.Log;
public class Bombardero extends NaveAlien {
public Bombardero(){
super(100);
Log.i("Ubicacion","Constructor del bombardero");
}
public void disparaArma(){
Log.i("Bombardero","Soltando bombas!");
}
}
En esta clase vamos a crear nuestras naves bombarderas, esta va a ser heredera de NaveAlien, lo primero que vemos es el constructor el cual usa la palabra super, esta palabra nos permite usar el constructor de nuestra clase maestra, en este caso como tenemos el constructor que setea el escudo lo enviamo con 100 y por ende nos creo la nave con este valor, luego escribimos en el log la creacion del bombardero, despues definimos el metodo disparaArma el cual unicamente escribira en el log un mensaje indicando su accion, con esto tenemos nuestra primera clase hija, para nuestro siguiente paso crearemos otra clase de la misma forma que antes pero con estos datos:
- Nombre: Caza
- Tipo: Class
Despues presionaremos Enter para generarla y una vez creada nuestra clase reemplazaremos el codigo generado por el existente:
Caza.java
package org.example.herencias;
import android.util.Log;
public class Caza extends NaveAlien {
public Caza(){
super(400);
Log.i("Ubicacion","Constructor del caza");
}
public void disparaArma(){
Log.i("Caza","Disparando lasers!");
}
}
Este es igual a la clase anterior, la unica diferencia es el valor del escudo y el mensaje al momento de disparar pero trabaja de la misma forma, una curiosidad sino copiaron y pegaron el codigo a medida que lo van definiendo les va a notificar que el codigo esta mal hasta que definan a disparaArma, con esto realizado tenemos otra clase hija de NaveAlien y para nuestra ultima modificacion modificaremos a MainActivity de la siguiente manera:
MainActivity.java
package org.example.herencias;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Caza bebop = new Caza();
Bombardero yamato = new Bombardero();
bebop.nombreNave = "Bebop";
yamato.nombreNave = "Yamato";
Log.i(bebop.nombreNave,""+bebop.getFuerzaEscudo());
Log.i(yamato.nombreNave,""+yamato.getFuerzaEscudo());
for(int i=0; i<4; i++)
{
yamato.disparaArma();
bebop.impactoDetectado();
Log.i(bebop.nombreNave,""+bebop.getFuerzaEscudo());
bebop.disparaArma();
yamato.impactoDetectado();
Log.i(yamato.nombreNave,""+yamato.getFuerzaEscudo());
}
Log.i(bebop.nombreNave,""+bebop.getFuerzaEscudo());
Log.i(yamato.nombreNave,""+yamato.getFuerzaEscudo());
}
}
En este codigo volveremos a crear dos objetos, uno de tipo Caza llamado bebop y otro de tipo Bombardero llamado yamato, despues les asignamos los nombres a cada uno de las naves, el siguiente paso sera mostrar los valores de cada escudo, lo que sigue es un bucle for donde primero dispara yamato, impacta en el bebop y despues mostramos el valor de su escudo, despues disparamos con el bebop, impacta en el yamato para luego mostrar el valor del escudo y esto lo haremos cuatro veces, una vez terminado el ciclo mostramos los valores de los escudos de cada nave, si lo compilamos y probamos deberemos obtener un log como este:
05-22 01:42:33.186 4431-4431/org.example.herencias I/Ubicacion: Constructor del caza
05-22 01:42:33.187 4431-4431/org.example.herencias I/Ubicacion: Constructor del bombardero
05-22 01:42:33.187 4431-4431/org.example.herencias I/Bebop: 400
05-22 01:42:33.187 4431-4431/org.example.herencias I/Yamato: 100
05-22 01:42:33.187 4431-4431/org.example.herencias I/Bombardero: Soltando bombas!
05-22 01:42:33.187 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.187 4431-4431/org.example.herencias I/Bebop: 375
05-22 01:42:33.187 4431-4431/org.example.herencias I/Caza: Disparando lasers!
05-22 01:42:33.187 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.187 4431-4431/org.example.herencias I/Yamato: 75
05-22 01:42:33.187 4431-4431/org.example.herencias I/Bombardero: Soltando bombas!
05-22 01:42:33.187 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.190 4431-4431/org.example.herencias I/Bebop: 350
05-22 01:42:33.190 4431-4431/org.example.herencias I/Caza: Disparando lasers!
05-22 01:42:33.190 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.190 4431-4431/org.example.herencias I/Yamato: 50
05-22 01:42:33.190 4431-4431/org.example.herencias I/Bombardero: Soltando bombas!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Bebop: 325
05-22 01:42:33.191 4431-4431/org.example.herencias I/Caza: Disparando lasers!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Yamato: 25
05-22 01:42:33.191 4431-4431/org.example.herencias I/Bombardero: Soltando bombas!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Bebop: 300
05-22 01:42:33.191 4431-4431/org.example.herencias I/Caza: Disparando lasers!
05-22 01:42:33.191 4431-4431/org.example.herencias I/Ahi vienen: Bam!!
05-22 01:42:33.198 4431-4431/org.example.herencias I/QEPD: Yamato fue destruida
05-22 01:42:33.198 4431-4431/org.example.herencias I/Yamato: 0
05-22 01:42:33.198 4431-4431/org.example.herencias I/Bebop: 300
05-22 01:42:33.198 4431-4431/org.example.herencias I/Yamato: 0
En este bloque de log podemos ver exactamente lo que le solicitamos al programa que haga y como yamato tiene un valor de cero en su escudo nos muestra que fue destruido y por ultimo nos muestra los valores de los escudos.
En este ejemplo vimos como creamos una clase maestra llamada NaveAlien la cual hace de molde para los distintos tipos de naves que podemos tener en una flotilla, despues creamos dos clases que representan dos tipos de naves, en ellas heredaremos las variables para el escudo y el nombre, despues usaremos el prototipo para disparar donde lo definiremos en cada nave, esto es lo mejor de la herencia donde podemos crear una clase que se encargara de los elementos base y despues en cada clase hija podemos no solamente usar estos sino tambien redefinir metodos o definir metodos previos.
En resumen, hoy hemos visto herencia, que es, para que se usa, como nos puede ser util, cuales son los beneficios que nos trae, el porque es uno de los pilares para la programacion orientada a objetos, por ultimo tambien analizamos un ejemplo donde pudimos ponerlo en practica, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.00