Herencia en Java, con ejemplos


El proyecto de este post lo puedes descargar pulsando AQUI.

La Herencia es uno de los 4 pilares de la programación orientada a objetos (POO) junto con la Abstracción, Encapsulació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.

Comparte esta entrada en:
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

150 thoughts on “Herencia en Java, con ejemplos”

  1. Buenas tardes estimado , tengo el siguiente ejercicio y no se por donde comenzar:
    «Cree una nueva clase denomina empresa mixta que sea capaz de heredar algunas propiedades de las empresas públicas, y otras de las empresas privadas, seleccione usted métodos y atributos que considere se deben heredar» todas de la clase principal empresa.
    me puede orientar por favor. Gracias

    1. Tal cual dice el enunciado te piden una clase «EmpresasGeneral» de la que hereden «EmpresasPublicas» y «EmpresasPrivadas».

  2. Hola.
    Me he encontrado un código que tengo que modificar y que está implementado así.
    Una Clase llamada producto y declarada así:

    public abstract class Producto implements Serialzable

    y otra que hereda de la anterior declarada:

    public abstract class Conjunto implements Serializable

    Por favor, ¿me puede ayudar alguien y decir qué significa?

    Gracias y un saludo.

    1. Normalmente una clase se hace Serializable para poder guardar en disco o enviar ese objeto a otro sitio (para que se pueda serializar), de otra manera no se podría.

      Por ejemplo, podrías hacer:

      Producto miProducto = new Producto();
      // Añadir valores a miProducto, quizás con setters.
      
      //Guardar el objeto a disco (el objeto Producto debe ser Serializable):
      FileOutputStream fos = new FileOutputStream("ruta/hasta/el/fichero.out");
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(miProducto);
      
  3. hola, no quiero la tarea, pero si quiero que me ayuden a analizar el siguiente planteamiento, lo que necesito saber es como aplicar herencias aqui, por mas vueltas que le doy, no consigo llegar a algo coherente:
    La secretaria del área técnica encarga de los horarios clase, en este periodo solicita un software que permita automatizar la generación de dichos horarios a partir de la siguiente información:

    Las asignaturas por curso.
    Las asignaturas por docente.
    Las aulas disponibles para clases.
    De cada docente hay que guardar: cédula, nombre, sección departamental y departamento al que pertenece. Cada departamento tiene un nombre. Las asignaturas tienen un nombre y un número de créditos, que indica el número de horas de docencia a la semana (1 crédito equivale a 3 horas).

    Hay dos tipos de asignaturas: las que son teóricas, y las que son prácticas, estas últimas deben tener asociado el sistema operativo a emplear. Igualmente hay dos tipos de aulas: para clases de teoría y para clases de laboratorio (asignaturas prácticas). En general, las aulas tienen un nombre, una ubicación y una capacidad. De las aulas de teoría interesa conocer el tipo de pupitre (abatible o fijo), y de las de prácticas se quiere saber si disponen de altavoces y cámara de videoconferencia. Los posibles cursos son cinco, de primero a quinto, pero interesa que el sistema sea abierto para poder evolucionar a situaciones con un número de cursos mayor o menor. Hay que tener en cuenta que una asignatura sólo puede formar parte de un único curso. Los días de clase van de lunes a viernes, y las horas posibles son de 8:30 a 14:30 y de 15:30 a 21:30. Las asignaturas se imparten en bloques de 1 hora.

    Los docentes deben introducir en el sistema la información de las asignaturas que imparten. También deben elegir los tres días para dictar clase. Este dato es utilizado por la secretaria para generar automáticamente los horarios. No obstante, puede darse el caso de que la generación automática no obtenga una solución completa al problema de los horarios y sea preciso que se retoque manualmente la asignación de horas de clase a las asignaturas en las diferentes aulas. De esto, y de la introducción del resto de informaciones necesarias, también se encarga la secretaria.

    El sistema también debe permitir la consulta de horarios por parte de los alumnos.

    1. Estaría bien por implementar unos diagramas con las herencias que necesites y los listados con los objetos (por ejemplo, un «curso» tiene «asignaturas», te debe dar pista de que te piden una clase Curso que tenga un listado Asignaturas).
      El resto creo que te piden código secuencial y un tipo de interfaz (supongo que te valdrá con el input).
      Creo que te he dado bastante pista, así que ánimo con el resto!

  4. Hola estimados, no se si en el año 2022 aun respondan consultas por ayuda respecto del tema de herencias y POO.
    soy estudiante y estoy en programacion java, pero en mi ejercicio tengo unos poblemas respecto a las herencia, tengo 3 clases, Persona, Empleado y main (aca esta el menu de entrada de datos), pero al momento de agregar los empleados todo resulta bien y al listar a los empleados todo resulta bien, pero al buscar o eliminar un empleado, no me develve los datos del empleado por ejemplo en buscar….creo que herencia y POO tienen algunas restricciones al momento de implementarlas, porque tengo el DNI(rut) como String en la clase padre( persona) , aunque el sistema no me permite que DNI sea private y siempre hay algo malo…..pero usar el DNI en int ningun problema con los metodos buscar o eliminar.

    aca posteo el metodo en clase Empleado

    public String buscarEmpleado(String rut) {
    int i = 1;
    String rutb = null;
    StringBuilder sb = new StringBuilder();

    for(Empleado e : listaEmpleados){
    if(e.getRut().equals(rutb)){
    sb.append(«Datos del Empleado»).append(i).append(«\n»);
    sb.append(«—————————————–«).append(«\n»);
    sb.append(«Rut: «).append(e.getRut()).append(«\n»);
    sb.append(«Nombre: «).append(e.getNombre()).append(«\n»);
    sb.append(«Apellido: «).append(e.getApellido()).append(«\n»);
    sb.append(«Sexo: «).append(e.getSexo()).append(«\n»);
    sb.append(«Edad: «).append(e.getEdad()).append(«\n»);
    sb.append(«Sueldo Base: «).append(e.getSueldoBase()).append(«\n»);
    sb.append(«Cantidad Hijos: «).append(e.getCantHijos()).append(«\n»);
    i++;
    }

    }
    return sb.toString();
    }

    ————–clase Main——

    case 2:
    System.out.println(«Ingrese rut a buscar»);
    rut = read.next();
    sb=e.buscarEmpleado(rutb);
    //System.out.println(«Datos del empleado»);
    System.out.println(sb);
    break;

    saludos que esten muy bien..

    1. Sí, todavía respondemos, aunque cuando tenemos un momento.
      Creo que estás comparando en el «if(e.getRut().equals(rutb))» todo el rato con null (rutb) en vez de con el valor pasado «rut». Por eso no te lo encuentra.

  5. Hola tengo una duda, como harias tú una herencia de partes de una computadora? lo que intento hacer es un programa en base a eso pero no se como aplicarle la herencia.

    1. Supongo que es un ejercicio, por lo que pude que te valga con crear una clase llamada «Memoria», de la que extienda «DiscoDuro» y «RAM», por ejemplo.

  6. hola amigos, q pasa si por ejemplo la clase futbolisto tiene solo 4 atributos (id, nombre, apellidos, edad), o sea seria una clase hijha sion atributos, ya que utlizaria los atributos de la clase madre?

    1. Sí, podría ser perfectamente, pues los métodos que implemente sean diferentes a los de la clase padre, pero sus atributos los mismos.

  7. Ayuda porfis
    Problemática del Resolución de problemas y casos 3:

    (La clase Animales): Noé es el propietario de una tienda de animales domésticos y le ha pedido que escriba un sistema que administre el inventario y facturación de su tienda. En ella vende perros, gatos y peces. El programa deberá llevar la cuenta de la raza de los perros y el tipo de comida (en lata o seca) la raza de los gatos y si tienen garras o no; de los peces el tipo de pez y si es de agua dulce o salada. Para estas especificaciones cree el respectivo diagrama de clases y codifíquelo; Además cree una clase de prueba con un método para almacenar toda esta información anterior de los animales en un archivo de inventario, y dentro de la misma clase de prueba, o en otra clase Facturación, cree los métodos específicos para facturar la compra de cualquier (o los tres) tipo(s) de animales anteriores, según los siguientes parámetros: Todos los animales tiene un costo base de $60, al cual se le agrega o decrementa su valor según sus características: si se compra un perro que se alimenta con comida en lata, el costo incrementa en un 10% del costo base. Para los gatos con garras, el costo decrementa en un 5% y finalmente para los peces de agua dulce el costo se eleva en un 20% al costo base. Una vez calculados los valores totales de cada factura usted debe guardar dichos datos, únicamente con el Id. del cliente, su nombre más el monto total de la facturación.

    Sugerencia: Es mejor leer/escribir, desde/hacia entrada/salida de consola EN LA CLASE DE PRUEBA, y no en la jerarquía de clases.

  8. hola me podrían ayudar creando un código con herencia múltiple
    Implementar herencia simple de las siguientes clases en PYTHON

    Clase Persona
    Atributos:
    Cedula
    Nombre
    Apellido
    Sexo
    Rol
    Metodos:
    Hablar(Mensaje)
    getSexo()

    Clase Supervisor
    Atributo:
    tarea
    Metodos:
    getTareas()

    Clase Obrero
    Atributo:
    tarea
    Metodos:
    getTareas()

  9. Cordial saludo y un favor:

    Venga se puede dar el caso de: ¿Herencia y agregación? Por ejemplo: Tengo dos clases y en una existen atributos que son subconjunto de la otra, pero también tiene una referencia desde la clase hija a la clase madre.

    Agradezco la orientación.

    1. Para llamar a cualquier método o variable de la clase padre, en Java se usa la palabra reservada «super» (se usa igual que «this»).
      Un ejemplo:

      public class Padre {
          public void metodoPadre() {
             // La el método de la clase padre hace algo
          }
      }
      
      
      public class Hija extends Padre{
      
          // Sobrescribir el método de la clase Padre
          public void metodoPadre() {
             // El hijo puede tener cualquier código y cuando quiera llamar al metodoPadrede la clase Padre (con el código de la clase Padre) utilizará super:
             super.metodoPadre();
      
             // Como recordatorio, los métodos de la clase hijo se llaman con this:
             this.metodoHijo();
          }
      
          // Método de la clase hija (que no está en la clase Padre)
          public void metodoHijo() {
             // Este método tendrá cualquier código y si quiere llamar al metodoPadre pero de la clase Padre se usará super:
             super.metodoPadre();
      
             // Si quiere llamar al método sobrescrito en esta clase, como está a su nivel usará this:
             this.metodoPadre();
          }
      
          // Nota: este es un código de ejemplo sin fines de ejecución, pues tiene el problema de que es circular en la clase hijo (el metodoHijo llama a metodoPadre y viceversa).
      }
      
  10. Hola, por un lado excelente explicación y por otro tengo una consulta. Veo que creaste los objetos (Entrenador, Futbolista, Masajista) y luego los agregaste al ArrayList. En caso que quieras mostrar toda la información de los 3 como se haría? Porque veo que recorriste la lista pero solo mostraste el Nombre y Apellido. Pero en caso que quieras mostrar toda la información que pusiste, como seria?

    1. Buenas Simon.
      Sería igual, lo único que en la explicación se han resumido los getters y setters para que no quedara tan denso el artículo. Los tienes todos en GitHub en: https://github.com/jarroba/HerenciaJava/blob/master/src/Seleccion/SeleccionFutbol.java Como puedes ver en la clase completa de SeleccionFutbol están tanto getNombre y getApellido como el resto de «gets», por lo que se haría igual:

      for (SeleccionFutbol integrante : integrantes) {
          System.out.print(integrante.getNombre());
          System.out.print(integrante.getApellidos());
          System.out.print(integrante.getId());
          System.out.print(integrante.getEdad());
      }
      
      1. Hola! Y si además de nombre, apellido, ID y edad quisieras mostrar el «tipo» de persona que es (Futbolista, Entrenador o Masajista), cómo lo harías?

  11. Hola… Tengo una consulta:
    ¿Qué pasa si el entrenado también es futbolista?
    ¿Cómo se resuelve ese problema?

    Saludos

    1. Hola Daniel.
      Entonces Entrenador no heredará de SelecciónFutbol, sino de Futbolista (de esta manera hereda a la vez de Futbolista y SeleccionFutbol).

      1. Buenas noches, me queda una duda con respecto a esta aclaración.. si entrenador heredará de futbolista esto quiere decir que obligatoriamente debería ser futbolista. Pero si quisiera que pudiese ser uno u otro o los dos a la vez? En ese caso, como lo resuelvo?
        Muchas gracias, saludos.

        1. La herencia de herencia serviría para heredar los dos a la vez (la clase H hereda de la clase P, por lo que una clase X que herede de H heredará también de P).
          En otros lenguajes existe la herencia múltiple que permite heredar de una clase o de otra o de ambas, pero en Java no. En Java se puede simular una herencia múltiple con interfaces, por ejemplo:

          interface Padre1 {
              default void metodo() {
                  System.out.println("Método por defecto Padre1");
              }
          }
            
          interface Padre2 {
              default void metodo() {
                  System.out.println("Método por defecto Padre2");
              }
          }
            
          
          class ClaseHija implements Padre1 , Padre2 {
          
              // Método sobrescrito
              public void metodo(){
                  // Llamar al método del Padre1
                  Padre1.super.metodo();
            
                  // Llamar al método del Padre2
                  Padre2.super.metodo();
              }
            
          }
          
          class ClasePrincipal {
              public static void main(String[] args) {
                  ClaseHija hijo = new ClaseHija();
                  hijo.metodo();
              }
          }
          
          1. Muchas gracias por la respuesta!
            Utilizando su ejemplo de arriba: Si un entrenador no fuera futbolista (es decir, solo fuera entrenador) yo instanciaría la clase Entrenador y al heredar de Futbolista (Persona -> Futbolista -> Entrenador) los atributos propios de la clase anterior (Futbolista) inevitablemente quedarían vacíos o con el valor por defecto no?
            Y si por ejemplo iniesta fuese jugador y entrenador, y quisiera mostrar todos sus atributos es decir tanto los de persona como los de jugador y entrenador, como debería hacerlo?
            Saludos.

          2. Para que resulte más sencillo de entender la herencia, hay que entenderla como un «copia y pega de código»; es decir, un Hijo copiará todo el código del Padre, pero el código del Hijo sobrescribirá al del Padre (por ejemplo, si dos métodos se llaman igual tanto en el Padre como en el del Hijo, el Hijo utilizará su método por haber sobrescrito al del Padre, pero el resto de métodos que no se llamen igual estarán igualmente presentes en el Hijo).
            De este modo Persona->Futbolista->Entrenador, significará que Futbolista tiene todo el código de Persona (salvo lo que haya sobrescrito o añadido de más Futbolista), así mismo, Entrenador tendrá todo el código de Futbolista (con todo el anterior de Persona más el sobrescrito o añadido de Futbolista, además, del sobrescrito o añadido por Entrenador).
            En respuesta a tu pregunta, dependerá de la necesidad, por ejemplo, para un Entrenador que «no» es futbolista (con Persona->Futbolista->Entrenador) bastará con no utilizar los métodos de Futbolista (siempre que nos sirva, pues puede haberlos sobrescrito). Lo que suele ser mejor y más conveniente será crear otro Entrenador que no herede de Futbolista si realmente queremos que el Entrenador NO sea Futbolista (Persona -> Entrenador) y tener por otro lado el EntrenadorFutbolista para cuando necesitemos un Entrenador que SÍ sea Futbolista (Persona->Futbolista->EntrenadorFutbolista).

  12. Hola, su manera de explicar es bastante clara y gracias por ello. Estoy empezando en esto del desarrollo orientado a objetos y el paradigma funcional. Pero tengo una duda de cómo se debe representar las herencias en una base de datos relacional. Del ejemplo que planteó, cada clase debe ser una tabla o todo debería guardarse en una sola tabla?

    Gracias!

    1. Buenas Franco.
      Para representar los datos de una base de datos con clases Java lo más recomendable es utilizar clases Contract (una clase cuyas variables globales representan las columnas de una tabla con los get y set para estos; siendo cada instancia/objeto una fila con los datos).
      Si hubiera tablas que hereden de otras, puede que sea interesante hacer herencia de clases Contract para extenderlas, pero dependería de la necesidad.

  13. Elabora un proyecto en java que tenga dos clases:
    1. La primera va tener solo el método “main”, en el cual se va a crear un arreglo bidimensional de strings de 5X2; La primera columna del arreglo es para escribir nombres de personas, y la segunda para escribir la carrera.
    2. La segunda clase va a contener un método que permita agregar datos (nombre y carrera) en una fila del arreglo que se creó en la primera clase. Otro método que elimine filas del arreglo tomando como criterio el nombre. Otro método para modificar filas, tomando como criterio el nombre.
    si me pueden ayudar?

  14. Hola muy buena explicación
    Quería saber cual seria la manera correcta de por ejemplo
    recorrer en un for eich el array y solo mostrar los objetos de tipo futbolistas por ejemplo
    he visto por ahí que solo agregan un método booleando en cada clase hija, pero tengo la sensación de que o es la forma correcta de hacerlo
    me gustaría mucho que me ayudaras con esa duda
    gracias desde ya….

    1. Buenas Jose. Me alegra que te guste la explicación.
      Sobre tu pregunta, depende, poner un método que devuelva True si es Futbolista sería un modo; pero tendrías que crear el método esFutbolista en todas las clases, muy engorroso y malo para escalar si en un futuro añades otra clase te tienes que acordar de añadirlo; si creas una implementación de una clase abstracta con el método esFutbolista podrías solventar en parte el problema, aún así me parece matar moscas a cañonazos para lo que necesitas es más sencillo preguntar directamente con instance of (ojo, utilizar esta manera hay que evitarla pues no es buena práctica, pero para ciertos casos, como este puede ser una buena opción):
      if (objetoDuda instanceof Futbolista) {
      ...
      }

  15. me podrian ayudar con este ejercicio porfavor …..realizar un ejemplo de herencia entre vehículo, helicóptero y camioneta, colocar atributos generales que compartan tanto el helicóptero como la camioneta, y; atributos y métodos específicos de cada subclase (clases hijas).

      1. Buenas Fernando.

        Siempre es una buena actitud la disposición de ayudar.

        Disponemos de una vía de comunicación más amplia en el foro donde se puede poner el correo y otros datos https://jarroba.com/foro/ y si Tania lo ve correcto puede publicar en el foro como le he indicado.

        Por motivos de seguridad, principalmente para ahorrarte spam de terceros, voy a borrar tu teléfono personal del comentario.

    1. Buenas Tania. Podemos ayudarte con pistas y guías pero no hacerte el ejercicio por motivos éticos (más información en https://jarroba.com/faq/).

      Por lo que comentas, necesitarás crear una clase vehículo que sea padre de helicóptero y camioneta; luego siguiendo estos ejemplos es sencillo el resto.

      Por otro lado, si quieres explicar mejor lo que necesitas para poder ayudarte, tenemos disponible el foro en https://jarroba.com/foro/

  16. 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.

  17. 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

  18. 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

  19. 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

  20. 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.

  21. 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.

  22. 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.

  23. 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/

  24. 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.

  25. 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)

  26. 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

  27. 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()

  28. 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).

  29. 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

  30. 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.

  31. 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.

  32. 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();
        }
        }

  33. 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.

  34. 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

  35. 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)

  36. EXCELENTE !!!  MUY CLARO, AL GRANO COMO DEBE SER.

    P.D. CUANDO TUTORIAL DE ABSTRACCION Y ENCAPSULACION

    GRACIAS SALUDOS RICARDO

     

     

  37. 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.

  38. HOLA, UN FAVOR QUERIA PREGUNTARTE CON QUE APLICACION HACES LOS DISEÑOS DE TUS CLASES!!!!!!!!!!!!!!! GRACIAS

     

  39. 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 🙂

  40. 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.

  41. 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…

  42. 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();

  43. 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.

  44. 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!

  45. 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 🙂

  46. 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.

  47. 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

  48. 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 

  49. 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

  50. 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).

  51. 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.

  52. 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.

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies

ACEPTAR
Aviso de cookies