Object-oriented programming in Java
Classes, objects, constructors, encapsulation, inheritance, polymorphism and interfaces, with interactive examples.
Introduction to OOP
Object-Oriented Programming (OOP) is a programming paradigm that organizes code into "objects" that combine related data and behaviors. In Java, everything is an object (except primitive types).
Class
A template or mold that defines the properties and behaviors of an object. It's like a blueprint.
Object
A concrete instance of a class. It's the "real thing" created from the mold.
Classes and Objects
Class and Object Simulator
// Crear un objeto (instancia) de la clase CocheCoche miCoche = new Coche("Toyota", "Corolla", 2023);
// Usar métodos del objetomiCoche.acelerar(50);
miCoche.mostrarInfo();
Constructors
public class Estudiante {
private String nombre;
private int edad;
private String carrera;
// 1. Constructor por defecto (sin parámetros) public Estudiante() {
this.nombre = "Sin nombre";
this.edad = 18;
this.carrera = "No asignada";
}
// 2. Constructor con parámetros public Estudiante(String nombre, int edad, String carrera) {
this.nombre = nombre;
this.edad = edad;
this.carrera = carrera;
}
// 3. Constructor de copia public Estudiante(Estudiante otro) {
this.nombre = otro.nombre;
this.edad = otro.edad;
this.carrera = otro.carrera;
}
// 4. Constructor con algunos parámetros (sobrecarga) public Estudiante(String nombre, int edad) {
this(nombre, edad, "Ingeniería"); // Llama a otro constructor }
}
Interactive Demonstration
Access Modifiers
Public
Accessible from any class in any package
public class MiClase {
public int valor; // Accesible desde cualquier parte}
Private
Only accessible within the same class
public class MiClase {
private int secreto; // Solo esta clase puede acceder}
Protected
Accessible in the same class, package and subclasses
public class MiClase {
protected int familiar; // Clase, paquete y herederas}
Default
Only accessible in the same package (no modifier)
public class MiClase {
int paquete; // Solo clases en el mismo paquete}
| Modifier | Same Class | Same Package | Subclass | Anywhere |
|---|---|---|---|---|
private |
✓ | ✗ | ✗ | ✗ |
(default) |
✓ | ✓ | ✗ | ✗ |
protected |
✓ | ✓ | ✓ | ✗ |
public |
✓ | ✓ | ✓ | ✓ |
Encapsulation
Getters and Setters: Protecting the Data
Encapsulation hides a class's internal details and only exposes a controlled interface through public methods (getters and setters).
public class CuentaBancaria {
// Atributos PRIVADOS (encapsulados) private String titular;
private double saldo;
private String numeroCuenta;
// Constructor
public CuentaBancaria(String titular, double saldoInicial) {
this.titular = titular;
this.saldo = saldoInicial;
this.numeroCuenta = generarNumeroCuenta();
}
// GETTERS (métodos para leer) public String getTitular() {
return titular;
}
public double getSaldo() {
return saldo;
}
public String getNumeroCuenta() {
return numeroCuenta;
}
// SETTERS con validación (métodos para modificar) public void setTitular(String titular) {
if (titular != null && !titular.trim().isEmpty()) {
this.titular = titular;
}
}
public void depositar(double cantidad) {
if (cantidad > 0) {
saldo += cantidad;
}
}
public boolean retirar(double cantidad) {
if (cantidad > 0 && cantidad <= saldo) {
saldo -= cantidad;
return true;
}
return false;
}
private String generarNumeroCuenta() {
// Método privado, solo usado internamente return "ES" + (int)(Math.random() * 1000000000);
}
}
Inheritance
Inheritance Tree: People System
Inheritance allows creating new classes based on existing ones, reusing and extending their functionality.
Person
Student
Teacher
// CLASE BASEpublic class Persona {
protected String nombre;
protected int edad;
public void presentarse() {
System.out.println("Hola, soy " + nombre);
}
}
// HERENCIA: Estudiante ES UNA Personapublic class Estudiante extends Persona {
private String matricula;
// Sobrescritura de método @Override
public void presentarse() {
super.presentarse(); // Llama al método de la clase base System.out.println("Soy estudiante con matrícula: " + matricula);
}
public void estudiar() {
System.out.println(nombre + " está estudiando...");
}
}
// HERENCIA: Profesor ES UNA Personapublic class Profesor extends Persona {
private String especialidad;
@Override
public void presentarse() {
System.out.println("Soy el profesor " + nombre +
", especialista en " + especialidad);
}
public void enseñar() {
System.out.println(nombre + " está enseñando " + especialidad);
}
}
Polymorphism
One Name, Multiple Forms
Polymorphism allows objects of different classes to be treated as objects of a common class.
Rectangle
Class that calculates area and perimeter
Circle
Class that calculates area and perimeter
Triangle
Class that calculates area and perimeter
// INTERFAZ COMÚNpublic interface Figura {
double calcularArea();
double calcularPerimetro();
}
// CLASES QUE IMPLEMENTAN LA INTERFAZpublic class Rectangulo implements Figura {
private double base, altura;
@Override
public double calcularArea() {
return base * altura;
}
@Override
public double calcularPerimetro() {
return 2 * (base + altura);
}
}
public class Circulo implements Figura {
private double radio;
@Override
public double calcularArea() {
return Math.PI * radio * radio;
}
@Override
public double calcularPerimetro() {
return 2 * Math.PI * radio;
}
}
// USO POLIMÓRFICOFigura[] figuras = new Figura[3];
figuras[0] = new Rectangulo();
figuras[1] = new Circulo();
figuras[2] = new Triangulo();
// Mismo método, diferentes comportamientosfor (Figura figura : figuras) {
System.out.println("Área: " + figura.calcularArea());
System.out.println("Perímetro: " + figura.calcularPerimetro());
}
Abstract Classes and Interfaces
Comparison: Abstract vs Interfaces
// EJEMPLO DE CLASE ABSTRACTApublic abstract class Animal {
// Attributes protected String nombre;
protected int edad;
// Constructor
public Animal(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
// Método abstracto (DEBE ser implementado) public abstract void hacerSonido();
// Método concreto (YA está implementado) public void dormir() {
System.out.println(nombre + " está durmiendo...");
}
// Método final (NO puede ser sobrescrito) public final void respirar() {
System.out.println(nombre + " está respirando");
}
}
// EJEMPLO DE INTERFACEpublic interface Volador {
// Constante (implícitamente public static final) int ALTURA_MAXIMA = 10000;
// Método abstracto (implícitamente public abstract) void volar();
// Método default (Java 8+) default void aterrizar() {
System.out.println("Aterrizando...");
}
// Método static (Java 8+) static void mostrarInfo() {
System.out.println("Interface para objetos que vuelan");
}
// Método private (Java 9+) private void logVuelo() {
System.out.println("Registrando vuelo...");
}
}
// CLASE QUE USA AMBOSpublic class Pajaro extends Animal implements Volador {
public Pajaro(String nombre, int edad) {
super(nombre, edad);
}
@Override
public void hacerSonido() {
System.out.println("¡Pío pío!");
}
@Override
public void volar() {
System.out.println(nombre + " está volando a gran altura");
}
}
| Feature | Abstract Class | Interface |
|---|---|---|
| Attributes | ✓ (cualquier modificador) | Solo constantes (public static final) |
| Constructors | ✓ | ✗ |
| Abstract methods | ✓ (0 or more) | ✓ (todos hasta Java 8) |
| Concrete methods | ✓ | ✓ (default/static desde Java 8) |
| Multiple inheritance | ✗ (solo una clase) | ✓ (múltiples interfaces) |
| Modifiers | Any | Solo public (implícitamente) |
Overloading vs Overriding
Game: Spot the Difference
Drag the methods to the correct category:
Overloading (Overloading)
Same method name, different signature (parameters)
Overriding (Overriding)
Same name and signature in child class (inheritance)
// SOBRECARGA (OVERLOADING) - En la MISMA clasepublic class Calculadora {
// Versión 1: dos enteros public int sumar(int a, int b) {
return a + b;
}
// Versión 2: tres enteros public int sumar(int a, int b, int c) {
return a + b + c;
}
// Versión 3: dos doubles public double sumar(double a, double b) {
return a + b;
}
// Versión 4: array de enteros public int sumar(int[] numeros) {
int total = 0;
for (int num : numeros) {
total += num;
}
return total;
}
}
// SOBRESCRITURA (OVERRIDING) - En clase HIJApublic class Animal {
public void hacerSonido() {
System.out.println("El animal hace un sonido");
}
}
public class Perro extends Animal {
@Override // Anotación recomendada public void hacerSonido() {
System.out.println("¡Guau guau!");
}
}
public class Gato extends Animal {
@Override
public void hacerSonido() {
System.out.println("¡Miau miau!");
}
}
// USO POLIMÓRFICOAnimal miAnimal = new Perro();
miAnimal.hacerSonido(); // Output: ¡Guau guau!
Practical Exercises
Library System
Create a system for a library with the following classes:
- Book: Base class with title, author, ISBN and status attributes (available/borrowed)
- LibroDigital: Inherits from Libro, adds format (PDF, EPUB) and size in MB
- Username: Class with name, ID and list of borrowed books
- Library: Main class that manages books and users
Requirements: Encapsulation, inheritance, polymorphism and method overriding.
Geometric Shapes System
Implement a geometric shapes system using interfaces and abstract classes:
- Interface
Figurawith methodscalcularArea()andcalcularPerimetro() - Abstract class
FiguraGeometricathat implements some common methods - Concrete classes:
Circulo,Rectangulo,Triangulo - Class
CalculadoraAreasthat uses polymorphism
Employee System
Create a payroll system for different employee types:
- Abstract class
Empleadowith basic attributes and abstract methodcalcularSalario() - Concrete classes:
EmpleadoTiempoCompleto,EmpleadoPorHoras,EmpleadoComision - Interface
Bonificablewith methodaplicarBonificacion() - Method overloading for different hiring types
Card Game with OOP
Implement a card game system using all OOP concepts:
- Class
Cartawith rank and suit - Abstract class
Jugadorwith game strategies - Interfaces:
Jugable,Barajable - Class
Mazothat uses composition (list of Cartas) - Overloading for different game rules
- Polymorphism for different player types
Concept Quiz
Question 1: What is a class in OOP?
Summary and Best Practices
Key OOP Concepts
- Class: Mold/blueprint for creating objects
- Object: A concrete instance of a class
- Encapsulation: Hide internal details (private + getters/setters)
- Inheritance: Reuse and extend functionality (extends)
- Polymorphism: Multiple forms through a common interface
- Abstraction: Show only what's essential, hide complexity
OOP Best Practices
- Use descriptive names for classes and methods
- Follow the single responsibility principle
- Prefer composition over inheritance when possible
- Use appropriate access modifiers
- Document your classes and methods with JavaDoc
- Use interfaces to define clear contracts
- Avoid overly large classes ("god classes")
Common Errors
- Forgetting encapsulation (public attributes)
- Excessive inheritance (too many levels)
- Not using @Override when overriding
- Confusing overloading with overriding
- Creating "all-in-one" classes
- Not validating data in setters
- Using inheritance to share code instead of for "is-a" relationships
Quick Reference Sheet - POO
Define Class:
public class MiClase {
private atributo;
public MiClase() {}
public void metodo() {}
}
Inheritance:
public class Hijo extends Padre {
@Override
public void metodo() {
super.metodo(); // Llama al padre }
}
Interface:
public interface MiInterface {
void metodo();
}
public class Clase implements MiInterface {
@Override
public void metodo() {}
}
Abstract:
public abstract class Abstracta {
public abstract void metodo();
public void concreto() {}
}
Final OOP Test
Question 1 expression in 5