El polimorfisme és un concepte fonamental en la programació orientada a objectes (OOP) que permet que una interfície única sigui utilitzada per diferents tipus d'objectes. En Groovy, com en altres llenguatges orientats a objectes, el polimorfisme permet que una mateixa operació es comporti de manera diferent en funció de l'objecte que la implementa.

Conceptes Clau

  1. Polimorfisme de Sobrecàrrega (Overloading):

    • Permet definir múltiples mètodes amb el mateix nom però amb diferents signatures (paràmetres).
  2. Polimorfisme de Sobreescriptura (Overriding):

    • Permet que una subclasse proporcioni una implementació específica d'un mètode que ja està definit en la seva superclasse.
  3. Polimorfisme d'Interfície:

    • Permet que diferents classes implementin la mateixa interfície, i que els objectes d'aquestes classes puguin ser tractats de manera uniforme a través de la interfície comuna.

Exemples Pràctics

Polimorfisme de Sobrecàrrega

class Calculadora {
    int sumar(int a, int b) {
        return a + b
    }

    double sumar(double a, double b) {
        return a + b
    }

    int sumar(int a, int b, int c) {
        return a + b + c
    }
}

def calc = new Calculadora()
println calc.sumar(1, 2)          // Sortida: 3
println calc.sumar(1.5, 2.5)      // Sortida: 4.0
println calc.sumar(1, 2, 3)       // Sortida: 6

Polimorfisme de Sobreescriptura

class Animal {
    void ferSoroll() {
        println "L'animal fa un soroll"
    }
}

class Gos extends Animal {
    @Override
    void ferSoroll() {
        println "El gos borda"
    }
}

class Gat extends Animal {
    @Override
    void ferSoroll() {
        println "El gat miola"
    }
}

def animals = [new Gos(), new Gat(), new Animal()]
animals.each { it.ferSoroll() }
// Sortida:
// El gos borda
// El gat miola
// L'animal fa un soroll

Polimorfisme d'Interfície

interface Volador {
    void volar()
}

class Ocell implements Volador {
    @Override
    void volar() {
        println "L'ocell vola"
    }
}

class Avio implements Volador {
    @Override
    void volar() {
        println "L'avió vola"
    }
}

def voladors = [new Ocell(), new Avio()]
voladors.each { it.volar() }
// Sortida:
// L'ocell vola
// L'avió vola

Exercicis Pràctics

Exercici 1: Sobrecàrrega de Mètodes

Crea una classe CalculadoraAvançada que tingui mètodes per sumar, restar, multiplicar i dividir nombres enters i decimals. Implementa la sobrecàrrega de mètodes per a cada operació.

Exercici 2: Sobreescriptura de Mètodes

Crea una jerarquia de classes amb una superclasse Vehicle i subclasses Cotxe i Moto. Defineix un mètode moure a la superclasse i sobreescriu-lo a les subclasses per proporcionar implementacions específiques.

Exercici 3: Polimorfisme d'Interfície

Defineix una interfície Instrument amb un mètode tocar. Implementa aquesta interfície en classes Guitarra i Piano. Crea una llista d'instruments i fes que toquin tots els instruments de la llista.

Solucions

Solució a l'Exercici 1

class CalculadoraAvançada {
    int sumar(int a, int b) {
        return a + b
    }

    double sumar(double a, double b) {
        return a + b
    }

    int restar(int a, int b) {
        return a - b
    }

    double restar(double a, double b) {
        return a - b
    }

    int multiplicar(int a, int b) {
        return a * b
    }

    double multiplicar(double a, double b) {
        return a * b
    }

    int dividir(int a, int b) {
        return a / b
    }

    double dividir(double a, double b) {
        return a / b
    }
}

def calc = new CalculadoraAvançada()
println calc.sumar(1, 2)          // Sortida: 3
println calc.sumar(1.5, 2.5)      // Sortida: 4.0
println calc.restar(5, 3)         // Sortida: 2
println calc.restar(5.5, 3.5)     // Sortida: 2.0
println calc.multiplicar(2, 3)    // Sortida: 6
println calc.multiplicar(2.5, 3.5)// Sortida: 8.75
println calc.dividir(6, 3)        // Sortida: 2
println calc.dividir(7.5, 2.5)    // Sortida: 3.0

Solució a l'Exercici 2

class Vehicle {
    void moure() {
        println "El vehicle es mou"
    }
}

class Cotxe extends Vehicle {
    @Override
    void moure() {
        println "El cotxe es mou"
    }
}

class Moto extends Vehicle {
    @Override
    void moure() {
        println "La moto es mou"
    }
}

def vehicles = [new Cotxe(), new Moto(), new Vehicle()]
vehicles.each { it.moure() }
// Sortida:
// El cotxe es mou
// La moto es mou
// El vehicle es mou

Solució a l'Exercici 3

interface Instrument {
    void tocar()
}

class Guitarra implements Instrument {
    @Override
    void tocar() {
        println "La guitarra sona"
    }
}

class Piano implements Instrument {
    @Override
    void tocar() {
        println "El piano sona"
    }
}

def instruments = [new Guitarra(), new Piano()]
instruments.each { it.tocar() }
// Sortida:
// La guitarra sona
// El piano sona

Conclusió

El polimorfisme és una eina poderosa en la programació orientada a objectes que permet escriure codi més flexible i reutilitzable. En Groovy, el polimorfisme es pot aconseguir mitjançant la sobrecàrrega de mètodes, la sobreescriptura de mètodes i la implementació d'interfícies. Aquests conceptes permeten que diferents objectes responguin de manera diferent a les mateixes operacions, facilitant la creació de sistemes més modulars i mantenibles.

© Copyright 2024. Tots els drets reservats