Introducción
En este laboratorio, exploraremos dos conceptos fundamentales de la programación orientada a objetos en Java: herencia y polimorfismo. Estas poderosas características nos permiten crear código más organizado, eficiente y flexible. Comenzaremos explorando la herencia, que nos permite crear nuevas clases basadas en las existentes, y luego pasaremos al polimorfismo, que nos permite tratar objetos de diferentes clases de manera uniforme.
Al final de este laboratorio, podrás:
- Crear jerarquías de clases utilizando herencia
- Sobrescribir métodos en subclases
- Comprender y utilizar el polimorfismo
- Implementar clases y métodos abstractos
No te preocupes si estos términos suenan complejos; desglosaremos todo en pasos simples y fáciles de seguir. ¡Comencemos nuestro emocionante viaje para mejorar tus habilidades de programación en Java!
Creación de una Clase Base
Comenzaremos creando una clase base llamada Animal. Esta clase servirá como la base para nuestras otras clases.
Abre tu terminal y navega hasta el directorio de tu proyecto:
cd ~/projectCrea un nuevo archivo llamado
Animal.javautilizando el comandotouch:touch Animal.javaAbre
Animal.javaen tu editor de texto y agrega el siguiente código:public class Animal { private String name; private int age; public Animal(String name, int age) { this.name = name; this.age = age; } public void eat() { System.out.println(name + " is eating."); } public void sleep() { System.out.println(name + " is sleeping."); } public String getName() { return name; } public int getAge() { return age; } }Desglosemos este código:
- Definimos una clase llamada
Animalcon dos atributos:name(una cadena de texto) yage(un entero). - La palabra clave
privatesignifica que estos atributos solo se pueden acceder dentro de la clase. - Tenemos un constructor que inicializa estos atributos cuando se crea un objeto
Animal. - Tenemos dos métodos:
eat()ysleep(), que imprimen lo que el animal está haciendo. - También tenemos métodos "getter" (
getName()ygetAge()) que nos permiten acceder a los atributos privados desde fuera de la clase.
- Definimos una clase llamada
Guarda el archivo
Animal.java.

Ahora, compilemos nuestra clase
Animalpara asegurarnos de que no haya errores. En tu terminal, ejecuta:javac Animal.javaSi no hay mensajes de error, ¡tu clase se compiló correctamente!
Creando una Subclase
Ahora que tenemos nuestra clase base Animal, creemos una subclase llamada Dog. Esto demostrará cómo funciona la herencia en Java.
En tu terminal, crea un nuevo archivo llamado
Dog.java:touch Dog.javaAbre
Dog.javaen tu editor de texto y agrega el siguiente código:public class Dog extends Animal { private String breed; public Dog(String name, int age, String breed) { super(name, age); // Llama al constructor de la superclase this.breed = breed; } public String getBreed() { return breed; } }Desglosemos este nuevo código:
extends Animalle dice a Java queDoges una subclase deAnimal. Si bienDoghereda deAnimal, los atributos privadosnameyageenAnimalno son directamente accesibles enDog. Sin embargo,Dogpuede acceder a estos atributos a través de los métodos getter públicos heredadosgetName()ygetAge().- Hemos agregado un nuevo atributo
breedque es específico deDog. - El constructor toma tres parámetros. Utiliza
super(name, age)para llamar al constructor deAnimal, luego establece elbreed. - Hemos agregado un nuevo método
getBreed()que es específico deDog.
Guarda el archivo
Dog.java.Compila la clase
Dog:javac Dog.javaPodrías ver una advertencia sobre Animal.class, pero está bien por ahora.
Demostración de la Herencia
Ahora que tenemos nuestras clases Animal y Dog, creemos un programa para demostrar cómo funciona la herencia.
Crea un nuevo archivo llamado
InheritanceDemo.java:touch InheritanceDemo.javaAbre
InheritanceDemo.javay agrega el siguiente código:public class InheritanceDemo { public static void main(String[] args) { Animal genericAnimal = new Animal("Generic Animal", 5); Dog myDog = new Dog("Buddy", 3, "Labrador"); System.out.println("Demonstrating Animal class:"); genericAnimal.eat(); genericAnimal.sleep(); System.out.println("\nDemonstrating Dog class:"); myDog.eat(); // Inherited from Animal myDog.sleep(); // Inherited from Animal System.out.println("\nDog details:"); System.out.println("Name: " + myDog.getName()); // Inherited method System.out.println("Age: " + myDog.getAge()); // Inherited method System.out.println("Breed: " + myDog.getBreed()); // Dog-specific method } }Este programa crea instancias de las clases
AnimalyDogy demuestra cómo la claseDoghereda métodos de la claseAnimal.Guarda el archivo
InheritanceDemo.java.Compila y ejecuta el programa:
javac InheritanceDemo.java java InheritanceDemoDeberías ver una salida similar a esta:
Demonstrating Animal class: Generic Animal is eating. Generic Animal is sleeping. Demonstrating Dog class: Buddy is eating. Buddy is sleeping. Dog details: Name: Buddy Age: 3 Breed: Labrador
Esta demostración muestra cómo la clase Dog hereda atributos y métodos de la clase Animal, mientras que también agrega su propio atributo específico (breed) y método (getBreed()).
Sobrescritura de Métodos
La sobrescritura de métodos es una característica que permite a una subclase proporcionar una implementación específica de un método que ya está definido en su superclase. Veamos cómo funciona esto.
Abre
Dog.javay agrega el siguiente método:@Override public void eat() { System.out.println(getName() + " is eating dog food."); }Agrega este método dentro de la clase
Dog, pero fuera de cualquier otro método.La anotación
@Overridele dice al compilador que pretendemos sobrescribir un método de la superclase. No es obligatoria, pero es una buena práctica usarla.Guarda el archivo
Dog.java.Ahora, modifiquemos nuestro
InheritanceDemo.javapara demostrar la sobrescritura de métodos. AbreInheritanceDemo.javay reemplaza su contenido con:public class InheritanceDemo { public static void main(String[] args) { Animal genericAnimal = new Animal("Generic Animal", 5); Dog myDog = new Dog("Buddy", 3, "Labrador"); System.out.println("Demonstrating method overriding:"); genericAnimal.eat(); myDog.eat(); System.out.println("\nDemonstrating inherited method:"); myDog.sleep(); // This method is still inherited from Animal System.out.println("\nDog details:"); System.out.println("Name: " + myDog.getName()); System.out.println("Age: " + myDog.getAge()); System.out.println("Breed: " + myDog.getBreed()); } }Guarda el archivo
InheritanceDemo.java.Compila y ejecuta el programa actualizado:
javac Animal.java Dog.java InheritanceDemo.java java InheritanceDemo

Deberías ver una salida similar a esta:
Demonstrating method overriding:
Generic Animal is eating.
Buddy is eating dog food.
Demonstrating inherited method:
Buddy is sleeping.
Dog details:
Name: Buddy
Age: 3
Breed: Labrador
Esto demuestra cómo la sobrescritura de métodos permite a la clase Dog proporcionar su propia implementación del método eat(), mientras sigue heredando otros métodos como sleep() de la clase Animal.
Introducción al Polimorfismo
El polimorfismo es un concepto fundamental en la programación orientada a objetos que nos permite utilizar una referencia de clase base para referirnos a un objeto de subclase. Esto permite un código más flexible y reutilizable. Veamos cómo funciona.
Crea un nuevo archivo llamado
Cat.java:touch Cat.javaAbre
Cat.javay agrega el siguiente código:public class Cat extends Animal { public Cat(String name, int age) { super(name, age); } @Override public void eat() { System.out.println(getName() + " is eating fish."); } public void meow() { System.out.println(getName() + " says: Meow!"); } }Esto crea otra subclase de
Animalcon su propio métodoeat()y un nuevo métodomeow().Guarda el archivo
Cat.java.Ahora, actualicemos nuestro
InheritanceDemo.javapara demostrar el polimorfismo. Reemplaza su contenido con:public class InheritanceDemo { public static void main(String[] args) { Animal[] animals = new Animal[3]; animals[0] = new Animal("Generic Animal", 5); animals[1] = new Dog("Buddy", 3, "Labrador"); animals[2] = new Cat("Whiskers", 2); System.out.println("Demonstrating polymorphism:"); for (Animal animal : animals) { animal.eat(); // This will call the appropriate eat() method for each animal } System.out.println("\nAccessing specific methods:"); ((Dog) animals[1]).getBreed(); // We need to cast to Dog to call Dog-specific methods ((Cat) animals[2]).meow(); // We need to cast to Cat to call Cat-specific methods } }Este código crea un array de objetos
Animal, pero en realidad estamos almacenando una mezcla de objetosAnimal,DogyCaten él. Cuando llamamos aeat()en cada animal, Java llama automáticamente a la versión adecuada del método según el tipo real del objeto.Guarda el archivo
InheritanceDemo.java.Compila y ejecuta el programa actualizado:
javac Animal.java Dog.java Cat.java InheritanceDemo.java java InheritanceDemoDeberías ver una salida similar a esta:
Demonstrating polymorphism: Generic Animal is eating. Buddy is eating dog food. Whiskers is eating fish. Accessing specific methods: Whiskers says: Meow!
Esto demuestra el polimorfismo en acción. Somos capaces de tratar todos los objetos como objetos Animal, pero cuando llamamos al método eat(), cada objeto se comporta según la implementación específica de su clase.
Resumen
En este laboratorio, hemos explorado algunos conceptos clave de la programación orientada a objetos en Java:
- Herencia: Creamos una clase base
Animaly derivamos las clasesDogyCatde ella. Esto nos permitió reutilizar código y crear una jerarquía lógica de clases. - Sobrescritura de Métodos: Vimos cómo las subclases pueden proporcionar sus propias implementaciones de métodos definidos en la superclase, lo que permite un comportamiento más específico.
- Polimorfismo: Aprendimos cómo tratar objetos de diferentes clases de manera uniforme a través de su superclase común, lo que permite un código más flexible y reutilizable.
Estos conceptos son fundamentales para Java y la programación orientada a objetos en general. Nos permiten crear estructuras de código más organizadas, eficientes y flexibles. A medida que continúes tu viaje en Java, encontrarás que estos conceptos se utilizan ampliamente en aplicaciones más complejas.
Recuerda, la práctica es la clave para dominar estos conceptos.



