lunes, 22 de junio de 2020

Herencia en Java

Herencia en Java

La herencia es un pilar importante de OOP (Programación Orientada a Objetos). Es el mecanismo en Java por el cual una clase permite heredar las características (atributos y métodos) de otra clase. ... Hereda todas las variables y métodos definidos por la superclase y agrega sus propios elementos únicos.

La Herencia es uno de los 4 pilares de la programación orientada a objetos (POO) junto con la AbstracciónEncapsulación y Polimorfismo. Al principio cuesta un poco entender estos conceptos característicos del paradigma de la POO porque solemos venir de otro paradigma de programación como el paradigma de la programación estructurada (ver la entrada"Paradigmas de Programación), pero se ha de decir que la complejidad está en entender este nuevo paradigma y no en otra cosa. En esta entrada vamos a explicar de la mejor manera posible que es la herencia y lo vamos a explicar con un ejemplo.
Respecto a la herencia se han dado muchas definiciones como por ejemplo la siguiente: "La herencia es un mecanismo que permite la definición de una clase a partir de la definición de otra ya existente. La herencia permite compartir automáticamente métodos y datos entre clases, subclases y objetos.". Así de primeras esta definición es un poco difícil de digerir para aquellos que estéis empezando con la POO, así que vamos a intentar digerir esta definición con un ejemplo en el que veremos que la herencia no es más que un "Copy-Paste Dinámico" o una forma de "sacar factor común" al código que escribimos.
El ejemplo que proponemos es un caso en el que vamos a simular el comportamiento que tendrían los diferentes integrantes de la selección española de futbol; tanto los Futbolistas como el cuerpo técnico (Entrenadores, Masajistas, etc…). Para simular este comportamiento vamos a definir tres clases que van a representaran a objetos Futbolista, Entrenador y Masajista. De cada unos de ellos vamos a necesitar algunos datos que reflejaremos en los atributos y una serie de acciones que reflejaremos en sus métodos. Estos atributos y métodos los mostramos en el siguiente diagrama de clases:
NoHerencia_jarroba
NOTA: en este diagrama y en adelante no vamos a poner los constructores y métodos getter y setter con el fin de que el diagrama nos quede grande e "intendible" aunque en un buen diagrama de clases deberían aparecer para respetar el principio de encapsulación de la POO

Como se puede observar, vemos que en las tres clases tenemos atributos y métodos que son iguales ya que los tres tienen los atributos id, Nombre, Apellidos y Edad; y los tres tienen los métodos de Viajar y Concentrarse:
Herencia_jarroba
A nivel de código tenemos lo siguiente tras ver el diagrama de clases:
public class Futbolista
{

 private int id;
 private String Nombre;
 private String Apellidos;
 private int Edad;
 private int dorsal;
 private String demarcacion;

 // constructor, getter y setter

 public void Concentrarse() {
  ...
 }

 public void Viajar() {
  ...
 }

 public void jugarPartido() {
  ...
 }

 public void entrenar() {
  ...
 }
}
public class Entrenador
{

 private int id;
 private String Nombre;
 private String Apellidos;
 private int Edad;
 private String idFederacion;

 // constructor, getter y setter

 public void Concentrarse() {
  ...
 }

 public void Viajar() {
  ...
 }

 public void dirigirPartido() {
  ... 
 }

 public void dirigirEntreno() {
  ...
 }
}
public class Masajista
{

 private int id;
 private String Nombre;
 private String Apellidos;
 private int Edad;
 private String Titulacion;
 private int aniosExperiencia;

 // constructor, getter y setter

 public void Concentrarse() {
  ...
 }

 public void Viajar() {
  ...
 }

 public void darMasaje() {
  ...
 }
}
Lo que podemos ver en este punto es que estamos escribiendo mucho código repetido ya que las tres clases tienen métodos y atributos comunes, de ahi y como veremos enseguida, decimos que la herencia consiste en "sacar factor común" para no escribir código de más, por tanto lo que haremos sera crearnos una clase con el "código que es común a las tres clases" (a esta clase se le denomina en la herencia como "Clase Padre o SuperClase") y el código que es  especifico de cada clase, lo dejaremos en ella, siendo denominadas estas clases como "Clases Hijas", las cuales heredan de la clase padre todos los atributos y métodos públicos o protegidos. Es muy importante decir que las clases hijas no van a heredar nunca los atributos y métodos privados de la clase padre, así que mucho cuidado con esto. En resumen para que veáis la ventaja de la herencia, tenemos ahora una clase padre con 'n' lineas de código y tres clases hijas con 'a', 'b' y 'c' lineas de códigos respectivamente, por tanto si hecháis cuentas, hemos reducido nuestro código en '2n' líneas menos ya que antes teníamos '(n+a)+(n+b)+(n+c)' líneas de código y ahora tras aplicar herencia tenemos 'n+a+b+c' líneas, aunque también es cierto que tenemos una clase más, pero veremos un poco más adelante la ventaja de tener esa clase padre. En resumen, al "sacar factor común" y aplicar herencia, tenemos las siguientes clases:
HerenciaV2_jarroba
A nivel de código, las clases quedarían implementadas de la siguiente forma:
 
public class SeleccionFutbol
{

 protected int id;
 protected String Nombre;
 protected String Apellidos;
 protected int Edad;

 // constructor, getter y setter

 public void Concentrarse() {
  ...
 }

 public void Viajar() {
  ...
 }
}
 
public class Futbolista extends SeleccionFutbol
{
 private int dorsal;
 private String demarcacion;

        public Futbolista() {
  super();
 }

 // getter y setter

 public void jugarPartido() {
  ...
 }

 public void entrenar() {
  ...
 }
}
public class Entrenador extends SeleccionFutbol
{

 private String idFederacion;

        public Entrenador() {
  super();
 }

 // getter y setter

 public void dirigirPartido() {
  ... 
 }

 public void dirigirEntreno() {
  ...
 }
}
public class Masajista extends SeleccionFutbol
{

 private String Titulacion;
 private int aniosExperiencia;

        public Masajista() {
  super();
 }

 // getter y setter

 public void darMasaje() {
  ...
 }
}
Como podéis observar ahora queda un código mucho más limpio, estructurado y con menos líneas de código, lo que lo hace más legible, cosa que es muy importante y lo que todavía lo hace más importante es que es un código reutilizable, lo que significa que ahora si queremos añadir más clases a nuestra aplicación como por ejemplo una clase Médico, Utiller@, Jefe/a de prensa etc. que pertenezcan también al equipo técnico de la selección Española, lo podemos hacer de forma muy sencilla ya que en la clase padre (SeleccionFutbol) tenemos implementado parte de sus datos y de su comportamiento y solo habrá que implementar los atributos y métodos propios de esa clase. ¿Empezáis a ver la utilidad de la herencia?.
Ahora si os habéis fijado bien en el código que se ha escrito y sino habéis tenido experiencia con la herencia en Java, habréis podido observar dos palabras reservadas "nuevas" como son "extends", "protected" y "super". Pues bien, ahora vamos a explicar el significado de ellas:
  • extends: Esta palabra reservada, indica a la clase hija cual va a ser su clase padre, es decir que por ejemplo en la clase Futbolista al poner "public class Futbolista extends SeleccionFutbol" le estamos indicando a la clase 'Futbolista' que su clase padre es la clase 'SeleccionFutbol' o dicho de otra manera para que se entienda mejor, al poner esto estamos haciendo un "copy-paste dinámico" diciendo a la clase 'Futbolista' que se 'copie' todos los atributos y métodos públicos o protegidos de la clase 'SeleccionFutbol'. De aquí viene esa 'definición' que dimos de que la herencia en un 'copy-paste dinámico'.
  • protected:  sirve para indicar un tipo de visibilidad de los atributos y métodos de la clase padre y significa que cuando un atributo es 'protected' o protegido, solo es visible ese atributo o método desde una de las clases hijas y no desde otra clase.
  • super: sirve para llamar al constructor de la clase padre. Quizás en el código que hemos puesto no se ha visto muy bien, pero a continuación lo mostramos de formas más clara, viendo el constructor de los objetos pasándole los atributos:
public class SeleccionFutbol {

 ......

 public SeleccionFutbol() {
 }

 public SeleccionFutbol(int id, String nombre, String apellidos, int edad) {
  this.id = id;
  this.Nombre = nombre;
  this.Apellidos = apellidos;
  this.Edad = edad;
 }
 ......
public class Futbolista extends SeleccionFutbol {
 ......
 public Futbolista() {
  super();
 }

 public Futbolista(int id, String nombre, String apellidos, int edad, int dorsal, String demarcacion) {
  super(id, nombre, apellidos, edad);
  this.dorsal = dorsal;
  this.demarcacion = demarcacion;
 }
 ......
Hasta aquí todo correcto, pero ahora vamos a ver como trabajamos con estas clases. Para ver este funcionamiento de forma clara y sencilla vamos a trabajar con un objeto de cada clase y vamos a ver como se crean y de que forma ejecutan sus método. Para ello empecemos mostrando el siguiente fragmento de código:
public class Main {

 // ArrayList de objetos SeleccionFutbol. Idenpendientemente de la clase hija a la que pertenezca el objeto
 public static ArrayList<SeleccionFutbol> integrantes = new ArrayList<SeleccionFutbol>();

 public static void main(String[] args) {

  Entrenador delBosque = new Entrenador(1, "Vicente", "Del Bosque", 60, "284EZ89");
  Futbolista iniesta = new Futbolista(2, "Andres", "Iniesta", 29, 6, "Interior Derecho");
  Masajista raulMartinez = new Masajista(3, "Raúl", "Martinez", 41, "Licenciado en Fisioterapia", 18);

  integrantes.add(delBosque);
  integrantes.add(iniesta);
  integrantes.add(raulMartinez);

  // CONCENTRACION
  System.out.println("Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo método)");
  for (SeleccionFutbol integrante : integrantes) {
   System.out.print(integrante.getNombre()+" "+integrante.getApellidos()+" -> ");
   integrante.Concentrarse();
  }

  // VIAJE
  System.out.println("nTodos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo método)");
  for (SeleccionFutbol integrante : integrantes) {
   System.out.print(integrante.getNombre()+" "+integrante.getApellidos()+" -> ");
   integrante.Viajar();
  }
 ......
Lo primero que vemos es que nos creamos un objeto de cada clase, pasándole los atributos al constructor como parámetro y después "sorprendentemente" los metemos en un "ArrayList" de objetos de la clase "SeleccionFutbol" que es la clase padre. Esto evidentemente te lo permite hacer ya que todos los objetos son hijos de la misma clase padre. Luego como veis, recorremos el ArrayList y ejecutamos sus métodos "comunes" como son el 'Concentrarse' y el 'Viajar'. Este código da como salida lo siguiente:
Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo método)
Vicente Del Bosque -> Concentrarse
Andres Iniesta -> Concentrarse
Raúl Martinez -> Concentrarse

Todos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo método)
Vicente Del Bosque -> Viajar
Andres Iniesta -> Viajar
Raúl Martinez -> Viajar
Como veis al ejecutar todos el mismo método de la clase padre el código puesto funciona correctamente.
Posteriormente vamos a ejecutar código especifico de las clases hijas, de ahi que ahora no podamos recorrer el ArrayList y ejecutar el mismo método para todos los objetos ya que ahora esos objetos son únicos de la clases hijas. El código es el siguiente:
// ENTRENAMIENTO
System.out.println("nEntrenamiento: Solamente el entrenador y el futbolista tiene metodos para entrenar:");
System.out.print(delBosque.getNombre()+" "+delBosque.getApellidos()+" -> ");
delBosque.dirigirEntrenamiento();
System.out.print(iniesta.getNombre()+" "+iniesta.getApellidos()+" -> ");
iniesta.entrenar();

// MASAJE
System.out.println("nMasaje: Solo el masajista tiene el método para dar un masaje:");
System.out.print(raulMartinez.getNombre()+" "+raulMartinez.getApellidos()+" -> ");
raulMartinez.darMasaje();

// PARTIDO DE FUTBOL
System.out.println("nPartido de Fútbol: Solamente el entrenador y el futbolista tiene metodos para el partido de fútbol:");
System.out.print(delBosque.getNombre()+" "+delBosque.getApellidos()+" -> ");
delBosque.dirigirPartido();
System.out.print(iniesta.getNombre()+" "+iniesta.getApellidos()+" -> ");
iniesta.jugarPartido();
Como vemos aunque el entrenador y los futbolistas asistan a un entrenamiento, los dos hacen una función diferente en el mismo, por tanto hay que hacer métodos diferente para cada una de las clases. Ya veremos cuando hablemos del polimorfismo que podremos ejecutar el mismo método para clases diferentes y que esos métodos hagan cosas distintas. Como resultado al código mostrado tenemos lo siguiente:
Entrenamiento: Solamente el entrenador y el futbolista tiene metodos para entrenar:
Vicente Del Bosque -> Dirige un entrenamiento
Andres Iniesta -> Entrena

Masaje: Solo el masajista tiene el método para dar un masaje:
Raúl Martinez -> Da un masaje

Partido de Fútbol: Solamente el entrenador y el futbolista tiene metodos para el partido de fútbol:
Vicente Del Bosque -> Dirige un partido
Andres Iniesta -> Juega un partido

CONCLUSIONES Y ACLARACIONES:

Esto ha sido todo lo que hemos contado sobre la herencia en esta entrada. El tema de la herencia es un tema que puede ser un poco más complejo de lo que lo hemos contado aquí, ya que solo hemos contado lo que es la herencia simple (ya que Java por el momento es el único tipo de herencia que soporta) y no la herencia múltiple, que es un tipo de herencia en la que una clase hija puede tener varios padres, aunque por el momento si estáis empezando a aprender el concepto de la herencia, con la herencia simple tenéis más que suficiente. Para los que os estéis iniciando en el mundo de la ingeniería informática, habréis podido ver que hemos puesto unos ejemplo mostrando unos diagramas "un poco raros"; pues bien, estos diagramas se llaman diagramas de clases (que los hemos realizado con la herramienta web de www.genmymodel.com) y sirven para representar de forma gráfica los atributos y métodos de las clases y las relaciones entre ellos, utilizando el lenguaje UML del cual intentaremos hablar más adelante en otros tutoriales. Por último decir y aclarar que en esta entrada quizás no hemos utilizado una terminología correcta para explicar la herencia, pero lo hemos explicadode una forma algo distinta a como esta explicada por ahi para que los que empeceis podais entender la herencia desde otro punto de vista.
les doy otro alcance


   

 Safe Creative #1401310112503
Herencia en Java, con ejemplos por "www.jarroba.com" esta bajo una licencia Creative Commons
Reconocimiento-NoComercial-CompartirIgual 3.0 Unported License.
Creado a partir de la obra en www.jarroba.com

109 thoughts on “Herencia en Java, con ejemplos”

  1. Hola tengo que hacer una tarea en la que mi clase «tableta» se hereda de dos clases «padre» estuve leyendo el concepto de interface pero tengo dudas, siento que no es eso lo que debo usar pero no estoy segura.
    1. En Java solo puedes heredar de un padre. Para simular la multiherencia puedes utilizar Interface. O si puedes, que A herede de B y luego B herede ce C, así tienes que A y B son dos padres y C el hijo que utiliza a los dos padres.
  2. Buenos dias, una guia o enlace para conocer la herencia de jframe en netbeans. Tengo un jframe base y guardandolo como plantilla, me permite crear nuevos jframes pero siempre me sale problemas con los nombres repitiendo el nombre de la clase padre- Ademas algunos botones personalizados heradados en la clase hija se comportan superponiendose, lo cual no ocurre en el jframe padre. Quiero reutilizar codigo y ahorrar tiempo pero no lo logro. Gracias x la ayuda
  3. Hola a todos,
    Realmente soy novato, es mi primer año estudiando sistemas y comencé con Java.
    Mi duda es: Cual es la diferencia entre heredar o extender e importar una clase. (?)
    De ante mano, gracias.
    1. Buenas Carlos
      «extend» es heredar en Java (una clase puede heredar de otra clase en Java).
      Importar una clase sirve para utilizar una clase que esté en otro fichero de Java separado del que estás utilizando.
    2. Hola, tienes formas ampliar los servicios de tu clase, la primera es la composición, es cuando haces el import, ya que eso te permite crear instancias de esas clases en tu propia clase. Cuando usamos Scanner, estamos importando java.util.Scanner así lo podemos utilizar. Otra forma es la Herencia. El problema de esta técnica es que para realizar esto, las clases deben tener una relación. Imagina creas una clase Persona, que herede los métodos de Scanner, no tiene sentido, así que en algunos casos usas herencia si es que dos de tus clases comparten métodos en común no importa si su implementación es diferente, entonces depende del problema que tengas que resolver, usarás composición, herencia o ambos a la vez. Saludos
  4. Hola soy rosa me podrias dar un ej; en java de una emprasa Renta car tego que hacer un proyecto y no se como empezar
  5. Buen día ¿Cómo puedo heredar una composición?
    PadreClass 1 — composición —> PadreClass2
    | |
    | |
    | |
    hijo hijo
    ¿Solo agrego una colección?
    1. En Java solo puedes heredar de una clase, aunque puedes simular herencia múltiple con Interfaces.
      Si te es útil, podrías heredar con una clase padre a una hija y desde esta hija (que sería el nuevo padre) que herede otra hija.
      1. Hola Ramón buenas tardes
        Necesito asesoría para un proyecto que estoy desarrollando; me podría regalar su numero de contacto para comunicarme o correo electrónico?
        Gracias
        1. Buenas Wilfredo.
          Por este canal no damos asesoría individual. Si se quiere poner en contacto con nosotros tiene nuestros datos en cada una de nuestras fichas.
  6. Buenas tardes disculpa tengo un ejemplo de herencia para sacar el area y perimetro de un rectangulo y cuadrado como puedo hacer que se comparen y me digan si son iguales ya sea el area o el perimetro de alguo
    1. Entiendo que tendrás que heredar el rectángulo del cuadrado (suponiendo que el cuadrado sea la figura base y el rectángulo la extiende la funcionalidad), y luego sobrescribir el método del «perímetro» del padre (es decir, que esté el método del perímetro tanto en el padre como en el hijo).
    2. Hola tego que hacer un progama y quiero saber como puedo sacar cuantos goles saca un partido y y los partidos que juegan entre si
      1. Buenas Rosa.
        Teniendo los goles de los futbolistas puedes sumarlos por equipos y devolverlos. Por otro lado, teniendo cada futbolista un listado de los partidos que juegan también tendrías esa información.
  7. una duda se puede usar herencia desde otro proyecto es decir tengo un proyecto llamado encapsulamientofecha con una clase Fecha
    puedo utilizar la clase Fecha desde otro proyecto con el comado import encapsulamientofecha.Fecha; o la herencia solo puede ser aplicada a clases del mismo proyecto como en este ejemplo mostrado
    1. Tendrías que exportar las clases que quieres utilizar como biblioteca (JAR) e importarlo en el otro proyecto que quieres heredar.
  8. Disculpa pero en este ejemplo de herencia, la clase padre SeleccionFutbol, deberia ser abstracta, ya que no debieramos permitir que se pueda crear una instancia de este tipo.
    Saludos,
    Martin.
    1. Como bien dices lo más probable es que interesara que sea abstracta para no implementar la clase SeleccionFutbol. En este artículo dedicado a la herencia para que sea muy fácil de entender no añadimos la clase abstracta para no complicar el código y las explicaciones.
      Se cambia la clase SeleccionFutbol a abstracta en el siguiente artículo sobre polimorfismo en: https://jarroba.com/polimorfismo-en-java-parte-i-con-ejemplos/
  9. hola, primero que todo, muy buena la información, se entiende bien aunque ahora me acate a una duda en especifica:
    estoy realizando un programa en el cual tengo 3 clases distintas:
    cliente:
    -run
    -nombre
    -apellido
    -telefono
    -email
    vehiculo:
    -matricula
    -marca
    -modelo
    -color
    -año
    servicio:
    -serviciocontratado
    Estas son para un menu de agregar, editar, eliminar y listar, en el cual poseo una jtable que quiero optimizar, pero no se me ocurre como debiese crear una clase padre que las englobe, ademas que posteriormente conectare el programa a un sql.
    Seria de mucha ayuda si me lograsen ayudar o si tienen una mejor opcion a realizar… en estos momentos estoy trabajando con las 3 clases por separado dentro programa.
    1. Dependería de lo que necesites concretamente. Por ejemplo, si tus tres clases servicio, vehículo y cliente tuvieran que tener un método común para atacar a la base de datos, pues te interesaría un padre para no repetir código; pero lo dicho, depende mucho de lo que necesites y del código que ya tengas.
  10. hola, si tengo un arreglo de tipo personas, pero pueden entrar elementos del tipo estudiante y docentes, como puedo acceder a sus métodos o atributos específicos mientras voy recorriendo el arreglo?
    gracias y saludos.
    1. Si los estudiantes y docentes comparten interfaz o utilizan los métodos del padre, podrás utilizar sus métodos sin problema al recorrerlo en un bucle. Por ejemplo (en pseudocódigo):
      class Persona {
      void metodo_del_padre(){
      // Código del método del padre…
      }
      }
      public interface MiInterfaz{
      void metodo_de_la_interfaz();
      };
      class Estudiante extends Persona implements MiInterfaz {
      @Override
      void metodo_de_la_interfaz(){
      // Implementar…
      }
      }
      class Docente extends Persona implements MiInterfaz {
      @Override
      void metodo_de_la_interfaz(){
      // Implementar…
      }
      }
      // Creamos la lista y le añadimos elementos:
      List<Persona> listaDePersonas = new ArrayList<Persona>();
      Estudiante estudiante = new Estudiante();
      listaDePersonas.add(estudiante);
      Estudiante docente = new Docente();
      anilistaDePersonas.add(docente );
      // Dentro del for puedes llamar a los método comunes
      for (Persona persona: listaDePersonas) {
      persona.metodo_del_padre();
      persona.metodo_de_la_interfaz();
      }
      // Sin embargo, para que sea un método específico ya habría que mirar otra manera de implementarlo, posiblemente con un if preguntando de qué tipo es la «persona» pasada (si es Docente o Estudiante)
  11. Excelente explicación, se me hizo bastante comprensible, solo tengo una duda con respecto al modificador de acceso de los atributos de la clase padre, tiene alguna complicación o algún efecto, si en lugar de que sean protegidos (protected), sean de cualquier otro tipo pero encapsulados por ejemplo que sean tipo privados (private).
    1. La gracia de que sean las variables/métodos protected es que solo puedan acceder sus hijos (y la misma clase padre) y nadie más. Si son private no podrán acceder ni sus hijos (solo la misma clase), y si son public podrá acceder todos (sean o no sus hijos).
    1. Aplicando lo explicado en el artículo sería:
      -DOCENTE hereda de PERSONA
      -ESTUDIANTE hereda de PERSONA
  12. Hola, Si modifico el metodo del padre en la clase hijo, y quiero utilizar ese mismo metodo pero de la clase padre en el main como podria hacerlo?
    1. Supongo que tienes algo así como padre:

      public class ClasePadre
      {
      public void MiMetodoClasePadre() {
      ...
      }
      }
      Y en la clase hija lo sobrescribes:

      public class ClaseHija extends ClasePadre
      {
      @Override
      public void MiMetodoClasePadre() {
      ...
      }
      }

      En el Main o donde quieras, si instancias a la ClasePadre utilizarás el método original.

      ClasePadre objetoPadre = new ClasePadre();
      objetoPadre.MiMetodoClasePadre()

      Sin embargo, si instancias la ClaseHija utilizarás el método sobrescrito (y no el de ClasePadre):

      ClasePadre ClaseHija = new ClaseHija();
      ClaseHija.MiMetodoClasePadre()
      // O más correcto para el polimorfismo y desacoplar los módulos:
      ClasePadre ClasePadre = new ClaseHija();
      ClaseHija.MiMetodoClasePadre()
  13. EXCELENTE
    No hay mas, te felicito, uno descarga libros o los compra , orientados a POO , comienza a leerlos bien feliz y BAM te empiezan a enrollar demasiado con los conceptos, con los «ejemplos» (que en su mayoría son de nominas) y ya para la hoja 300 no entendiste ni maíz, pero tu , aqui con tu ejemplo prácticamente resumiste 56 hojas de lo mismo , y mejor aun , diste un ejemplo mas «realista».
    1. Nos alegra que te haya servido 🙂
      Los artículos que publicamos procuramos que sean lo más resumidos posibles y que aporten lo máximo con ejemplos reales.
    1. Aunque no es necesario poner el vacío en la clase padre, aquí lo ponemos para que se vea como funciona la herencia con uno o dos constructores.
      Cuando alguien instancia un objeto de la clase hija (en este ejemplo «Futbolista»), por ejemplo:
      Futbolista MiFutbolista = new Futbolista(1, "mi nombre", "mi apellido", 25, 100, "mi demarcacion");
      Lo primero que hará este objeto será llamar al constructor de la clase padre (en este caso «SeleccionFutbol») para instanciar el objeto del que hereda. Se instancia llamando a super() sería, que desde el objeto de la clase hija sería como si hiciese:
      SeleccionFutbol MiSeleccionFutbol = new SeleccionFutbol();
      O en el otro ejemplo del segundo constructor con parámetros, el super(id, nombre, apellidos, edad) sería como si el objeto de la clase hija lo instanciara así:
      SeleccionFutbol MiSeleccionFutbol = new SeleccionFutbol(1, "mi nombre", "mi apellido", 25);
      Es decir, depende del constructor de la clase hija al que llamemos, llamaremos a uno u otro de la clase padre. En la clase padre si no se pone el constructor vacío es como si lo pones vacío (simplemente ocupa más código).
  14. Hola que tal, excelente manera de explicar y muy entendible todo, te felicito sigue así.. igual modifique algunas cosas por ejemplo el mensaje lo daba desde el método para hacer mas corto el Main
  15. Hola.
    Está excelente, con las analogías está más claro, llevo buen tiempo tratando con libros, de hecho me brinque el java por otros lenguajes, como bien dices lo difícil es entender los conceptos de paradigma, utilice java solo para el acceso a bases de datos, pero ahora voy a sacar provecho de su potencial.
    Un saludo.
  16. Muy buen aporte 😀
    Pero tengo una duda que la he traído por un tiempo, ¿los miembros de clase estáticos pueden ser hederados también a sus subclases? Eso es algo que no he encontrado respuesta aún o.O.
    Saludos.
  17. Muchas gracias, esta explicación me ha parecido muy clara y fácil de entender 🙂 , es justamente lo que necesitamos quienes recién estamos conociendo el mundo de la programación.
      1. Aplicando la herencia puedes aplicar:
        – Composición: No muestres public (o protected) ciertas partes de la clase del padre. Estas partes se mantendrán vivas mientras dure el padre y morirán con él (la destrucción de la Clase supone la destrucción de la Parte). Por ejemplo:
        class MiClase {
        private Parte parte;
        MiClase() {
        parte = new Parte();
        }
        void hacerAlgoConLaParte() {
        parte.hacerAlgo();
        }
        }
        – Agregación: Muestra las partes del padre con protected o public (con setter y getter por ejemplo). Estas partes pueden ser extraídas o insertadas en el padre y por tanto no morirán con él, pero tampoco las controlará (la destrucción de la Clase NO supone la destrucción de la Parte). Por ejemplo:
        class MiClase {
        private Parte parte;
        void setParte(Parte parte) {
        this.parte = parte;
        }
        void hacerAlgoConLaParte() {
        // Comprobación previa que la «parte» existe, como por ejemplo: if (parte != null)
        parte.hacerAlgo();
        }
        }
  18. Te hago una consulta, si tengo un problema que al resolverlo veo varias clases, pero estas clases no tienen difetente comportamiento, sino que solo varia en los atributos, que manera tengo de mejorar ese codigo?

    Saludos! 
    1. No se si te he entendido bien, puede que con pasar como parámetros esos atributos a las funciones de una única clase valdría.
  19. Hola,
    Supon que tienes algo asì:
    Organizador(Clase)
               SeleccionFutbol(Super)
    Futbolista Entrenador Masajista (Hijas)
    dorsal(Atrib)

    Supon que quiero listar todos los dorsales de los futbolistas
    qué deberìa hacer?
    Salutis.
    1. Suponiendo que tienes todos los «dorsales» en una lista. Solo te quedaría recorrer la lista y llamar al método de la clase padre «Futbolista» para saber a qué futbolista pertenece el dorsal. Algo así:
      Dorsal dorsal = //Creas el dorsal con sus datos
      String nombreFutbolista = dorsal.getNombreFutbolista() //Desde Dorsal llama al método de la clase padre Futbolista
  20. Muy buena explicacion pero me quedo la duda, si puedo heredar de clases no abstractas, es decir, un ejemplo: si tengo una superclase Persona, no instanciable, de la que heredad Empleado y Jefe, ambas clases instanciables, y a su ves una clase EmpleadoExterno, que hereda de Empleado, es posible?
    1. Sí es posible, pues tendrías la herencia (Simbología de flecha invertida, que con carácteres represento como «<|--", significa "hereda de"):
      Persona <|-- Jefe
      Y por otro lado:
      Persona <|-- Empleado <|-- EmpleadoExterno
      1. disculpa amigo como puedo hacer para no insertar uno por uno los futbolistas,entrenador,masajista pero ya cuando este ejecutando no en el main
        1. Si te refieres a la parte:
          integrantes.add(delBosque);
          integrantes.add(iniesta);
          integrantes.add(raulMartinez);

          Tienes que añadir los add() para introducir cada uno. Si ya tuvieras el objeto «integrantes» en memoria con todo añadido no tienes que volver a añadirlos (pues ya estarán añadidos)
  21. EXCELENTE !!!  MUY CLARO, AL GRANO COMO DEBE SER.
    P.D. CUANDO TUTORIAL DE ABSTRACCION Y ENCAPSULACION
    GRACIAS SALUDOS RICARDO


  22. Hola tengo una duda y me gustaria que me ayudaran, tengo una super clase llamada persona, y en esa tengo una clase hija que es empleado, pero ahora
    debo hacer 3 clases hijas de empleado y no tengo idea de como. gracias de antemano.
    1. Tú requerimineto es solo una clase hija (empleado) solo debes hacer una sola clase hija, no hay cantidad de clase hijas obligatorias,
      Si por algúna razon necesitaras otra clase hija depende del modelo de datos que estes diseñando……
      Ejemplo. Modelo de datos de una universidad
      clase padre: personas
      clases hijas: empleados, estudiantes,visitantes
      clases hijas de empleados:  obreros, contratados
      clse hija de contratados: profesores, coordinadores
      Fijate que todo depende del modelo de servicio que estes diseñando, ya que si tu instancia de estudio no es una universidad si no una empresa cambia o se reducen el diseño de las clases.
      Espero te aclare la duda.
  23. HOLA, UN FAVOR QUERIA PREGUNTARTE CON QUE APLICACION HACES LOS DISEÑOS DE TUS CLASES!!!!!!!!!!!!!!! GRACIAS

  24. Que Barbaro!!! deberias de dar clases, te volverias millonario,  sos buenisimo para explicar, la mejor 
    MUCHAS GRACIAS!!!
    1. Gracias Elver!! Realmente queremos hacer cosas muy grandes dentro de nuestro contexto y facilitarlas a todo el mundo. A veces podemos con gran esfuerzo, otras nos gustaría ofrecer más pese a los medios de los que disponemos, aun con todo continuamos siempre que tenemos disponibilidad 🙂
  25. Buenas tengo una duda…
    Estoy haciendo una tpv y quiero guardar los objetos en un arraylist. Como voy a tener muchos métodos iguales he decidido hacer una superclase y que de ella se hereden los métodos add, remover…
    Tengo clase producto, cliente, venta…. Y todas ellas van a llamar a un método añadir de la superclase. Mi pregunta es:
    Donde defino los arraylist? En cada clase? En la superclase? Las paso como parámetros a los métodos y después les hago un return??
    Muchas gracias de antemano!
    1. Hola Toñi, esto depende un poco de la lógica de tu programa. Si cada clase hija va a utilizar un arrayList por cada instancia lo suyo es ponerlo en la clase Padre para reutilizarlo desde ahí y así reducir código.
  26. Hola. Antes que nada muchísimas gracias por tus artículos que son de mucha más calidad que más de un texto de Java que anda dando vueltas por algunos libros. De hecho trabajo en esto desde hace menos de un año y me ayudan mucho para mi labor diaria. Ahora estoy queriendo entender el por qué de cosas que siempre las hago de forma mecánica. Con respecto a mi consulta, entiendo que protected permite a los atributos de la super clase ser usados por las subclases como si fuera de forma local sin importar si está en el mismo paquete. Mientras que para los métodos permite ser invocados desde el método de otras clases que estén dentro del mismo paquete. PERO no me queda muy claro el uso de "protected" aplicada a los atributos de la superclase, osea, qué me cambiaría si estos fueran "public" (nunca lo vi por cierto) de que si fueran "protected" ya que un atributo con cualquiera de ambas opciones solo podría ser usado por una subclase. Después para "acceder" al mismo desde otra clase cualquiera se debe crear el objeto y acceder desde un método getter. Ojalá que puedas entender mi consulta que no sé si quedó clara porque es algo de lo que no logro darme cuenta.
    Saludo grande!
     
    1. Hola Chipo,
      La diferencia entre protected y public, para el ejemplo de este caso, es que si bien se podía acceder a los atributos y metodos, de la clase padre, instanciandolos como "public", se establecen protected para que unicamente los hijos que "hereden" de ella, puedan hacerlo, es decir, al estar protected, el padre esta solicitando que una clase tenga que heredarla para poder acceder a sus atributos y metodos…
  27. hola buenas tardes una preguntar para que el usuario introdujera los datos por ejemplo nombre apellido edad etc desde el teclado como seria

    1. Para introduccir datos por teclado desde la consola puedes utilizar Scanner, como por ejemplo:
      Scanner teclado = new Scanner(System.in);
      System.out.println(«Teclea un número entero: «);
      int numeroIntroducido = teclado.nextInt(); //Para Strings tienes que usar teclado.nextLine();
  28. Un articulo fabuloso, elegante y practico, que se sale de los tipicos ejemplos de herencia q se ven obvios. El ejemplo me encanto porque realmente todos hacen una funcion distinta pero se les trata igual y lo del array lo clavaste. Pero podrias explicar como serializar los arrayslist en 3 ficheros distintos, ya q son 3 las clases heredadas.
  29. Hola, su Web y explicaciones me parecen de lo mejor. Las explicaciones son claras para personas que empiezan en el mundo de la informática, porque no son explicaciones con mucho lenguaje técnico.En este caso he puesto dos constructores uno sin atributos y otro con atributos para poder inicializar el objeto con el propio constructor sin necesidad de crearme un objeto y luego tener que ir llamando a cada uno de los métodos “setter” para asignar un valor a los atributos, es simplemente por eso por lo que he hecho dos constructores para escribir algo menos de código en definitiva.cualquier clase, herede de algo o no, que tenga variables globales privadas no podrán ser accedidas desde ningún sitio que no sea desde dentro de su clase, por lo que si quieres acceder a éstas requieres poner unos getters y setters.
    La diferencia de poner getter o setter o poner las variables públicas (o protected si son heredadas) es la seguridad del objeto y por convención de los programadores.
    Un ejemplo de seguridad del objeto sería que si tienes una variable global como:
    public int noNumeroCero = 1;
    Y por cualquier cosa requieres que nunca sea cero (por ejemplo, porque vayas a usar la variable como divisor; sabemos que dividir entre cero da error), si pueden acceder desde fuera directamente al ser pública, podrán ponerte un cero y el programa fallar. Si ponemos getter o setter podemos hacer la comprobación en el propio setNoNumeroCero(). Evidentemente, dependiendo de la lógica del programa, se podría hacer la comprobación antes de usar la variable.
    SL2
      1. Hola Richard, esta plataforma es de paga? O es free? Hay unas muy buenas, como Balsamiq Mockups, pero de paga y para fines academicos pues buehh… Gracias por toda la ayuda!
  30. que lastima ivan bien, ..hasta que encontré los puntos suspensivos, y por ejemplo getNombre no lo encontré por ningún lado….
    1. Es que no los ponen pero van así en la clase padre:
      public String getNombre(){
      return this.Nombre;
      }
      public String getApellidos() {
      return this.Apellidos;
      }
      Tienes que hacer los métodos.
    2. Gracias Alias.
      Los getter y setter, de establecimiento u obtención de valores de las variables globales, se han obviado para que el artículo no quedara muy denso, y fuera sencillo de entender 🙂
  31. Tengo una duda, si yo quisiera dentro de la clase hija llamar un metodo de otra clase y ese metodo requiera el objeto herdado, de que forma podria solucionar eso.
    EJemplo.
    public clase1 extends clase2{
    clase3 objeto= new clase3();
    objeto.metodo1( — aqui necesito enviarle el objeto heredado, es decir el objeto de tipo clase2—);
    }
    cabe aclarar que debe ser ese objeto. no me sirve instanciar uno nuevo. debe ser ese con la informacion que se ha modificado en esa instancia..
    por otro lado muy buena entrada, muchas gracias por compartir el conocimiento y quisiera me pudieran responder.
    Gracias… nuevamente.
    Saludos.
  32. Buenas me parece muy interesante el tutorial…pero hay dos cosas que no he visto o faltan:
    1 – Como es que en el for utilizas otra «variable» integrante ? con integrantes ya puedes recorrer el arraylist no ? No veo la necesidad de utilizar otra variable.
    2 – en integrante.viajar o integrante.concentrarse… tendrias que poner un print en la definicion de cada accion no para que salga el mensaje de pantalla ?
    3 – No entiendo muy bien a que viene partido de futbol, no es clase ni superclase…. no habeis explicado para que se pone….
    Espero ayudar a otros que tengan las mismas dudas o parecidas. Gran trabajo
    Saludos
  33. Hola..!! Excelente explicación.
    Una pregunta la clase Futbolista también hereda el Id de la clase padre.?
    Es decir al momento de guardar los datos en una base de datos, el Id llave primaria de la clase padre, pasaría
    como llave foránea a la clase hija?, o tengo que crear una llave primaria para la clase hija?
    Muchas gracias.
    1. Hola Ronald.
      En la herencia se heredan todos los atributos de la clase padre, así que el id también lo hereda.
      Otra cosa es que te plantees (en una base de datos), meter todas las clases que heredan de una misma clase padre en una misma tabla o en tablas diferentes. Eso ya es un tema diferente, pero te aconsejaria que lo hicieses en tablas diferentes, salvo que utilizases bases de datos como MongoDB que lo podrias meter todo en una misma colección.
      Cualquier otra duda nos dices.
      SL2
      1. Hola, es posible que las clases hijas tengan un id diferente a la clase padre?
        por ejemplo, una clase Persona tiene el id nroDocumento, y las clases hijas Cliente y Empleado tienen sus sus id codCliente y codEmpleado respectivamente?
        Tambien es para almacenarlas en una bd 
  34. Será que me puede responder esta pregunta?; Puede un objeto heredar atributos y métodos de mas de un objeto padre? Que cualidad sustenta o impide esta posibilidad?
    1. Hola Julián.
      Eso que comentas se llama herencia múltiple y hasta la fecha Java no soporta herencia múltiple. Hay otros lenguajes como C++ que si tienen herencia múltiple pero si te soy sincero hasta la fecha no he hecho nada con herencia múltiple, aunque sabiendo bien el concepto de herencia seria fácil aplicarla.
      SL2
  35. Tengo una duda respecto a la palabra reservada «protected».
    Sé que de esta manera, todos aquellos atributos de una clase que vienen precedidos del modificador «protected» serán visibles desde todas las clases hijas de la clase abstracta donde se declara ese atributo protected.
    Así pues si en la clase Empleado definimos:
    public abstract class Empleado
    {
    protected int sueldo;
    . . .
    }
    entonces desde la clase Ejecutivo (que extiende de Empleado) se puede acceder al dato miembro sueldo, mientras que si se declara private no.
    Así pues… de qué me sirve poner protected, si la puedo poner private y acceder a ella mediante getters y setters???
    1. Hola Jorge,
      cualquier clase, herede de algo o no, que tenga variables globales privadas no podrán ser accedidas desde ningún sitio que no sea desde dentro de su clase, por lo que si quieres acceder a éstas requieres poner unos getters y setters.
      La diferencia de poner getter o setter o poner las variables públicas (o protected si son heredadas) es la seguridad del objeto y por convención de los programadores.
      Un ejemplo de seguridad del objeto sería que si tienes una variable global como:
      public int noNumeroCero = 1;
      Y por cualquier cosa requieres que nunca sea cero (por ejemplo, porque vayas a usar la variable como divisor; sabemos que dividir entre cero da error), si pueden acceder desde fuera directamente al ser pública, podrán ponerte un cero y el programa fallar. Si ponemos getter o setter podemos hacer la comprobación en el propio setNoNumeroCero(). Evidentemente, dependiendo de la lógica del programa, se podría hacer la comprobación antes de usar la variable.
      Principalmente los getter y setter son por convención, para si por ejemplo, yo te pasara una clase, tú sin tener que mirar mucho más que los getter y setter supieras como usar la clase.
      1. Gracias por responder! A ver si me ha quedado claro… el tema de usar o no getters y setters es por convención (¿quieres decir por estándar?), y también por seguridad, no?
        Vale, pero si tu me pasas una clase con una serie de atributos protected, yo podré, mediante sus setters cambiar sus valores aunque no sea en ninguna de sus clases hijas… entonces donde está la seguridad? o no les pondrías getters ni setters para que no pueda tocarlos?
        De esta manera lo natural sería NO poner setters a los atributos protected de cualquier clase abstracta (de manera que aseguramos su visibilidad) y usar sólo los getters y setters en las propiedades privadas que nos interesen, excluyendo aquellas que puedan resultar peligrosas tocarlas desde otro sitio.
        Lo he entendido bien?
        Gracias de nuevo!
        1. La seguridad puede implicar no tocar las variables globales con un private y no poner setter, esto lo que hace es que nadie fuera de la clase la pueda tocar. Con seguridad me refiero a que no se admita cualquier valor en la variable y haya que controlar la entrada del valor (lo que te decía en el ejemplo anterior de no permitir el cero).
          De todas maneras, por norma pon siempre los getter y setter (El único que se salva es si programas en Android; en donde está desaconsejado el uso de getter o setter para ahorro de tiempo de proceso, batería, etc; es la única excepción y aún así, muchos programadores los siguen usando).
  36. Hola gracias por los tutoriales me parecen muy buenos.
    Una pregunta, por que existen dos constructores en cada una de las clases? No entiendo por que uno esta vacio y el otro no.
    Gracias!
    1. Hola Andrés.
      En este caso he puesto dos constructores uno sin atributos y otro con atributos para poder inicializar el objeto con el propio constructor sin necesidad de crearme un objeto y luego tener que ir llamando a cada uno de los métodos «setter» para asignar un valor a los atributos, es simplemente por eso por lo que he hecho dos constructores para escribir algo menos de código en definitiva.
      SL2
      1. Ahh ya entiendo, muchas gracias.
        Los felicito por su blog hay muchas cosas en Java que me parecen excelentes.
        Gracias.
  37. Hola, su Web y explicaciones me parecen de lo mejor. Las explicaciones son claras para personas que empiezan en el mundo de la informática, porque no son explicaciones con mucho lenguaje técnico.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *
 
 
 
Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Insertar Editar Eliminar Registros con Función PHP MySQLi

Insertar Editar Eliminar Registros con Función PHP MySQLi a)  Insertar Registros INSERT INTO tabla_name ( column1 , column2 ,...) VALUES (...