El polimorfisme és un concepte fonamental en la programació orientada a objectes (OOP) que permet que una interfície única sigui utilitzada per a representar diferents tipus d'objectes. En Swift, el polimorfisme es pot aconseguir mitjançant l'ús de classes, protocols i herència. Aquest concepte permet que el mateix mètode pugui tenir comportaments diferents segons l'objecte que l'implementi.

Conceptes Clau

  1. Polimorfisme de Subtipus: Permet que una classe derivada sigui tractada com una instància de la seva classe base.
  2. Polimorfisme Paramètric: Permet que funcions o mètodes treballin amb qualsevol tipus de dades.
  3. Polimorfisme d'Ad Hoc: També conegut com sobrecàrrega de mètodes, permet que diferents mètodes amb el mateix nom tinguin diferents implementacions.

Exemples Pràctics

Polimorfisme de Subtipus

En aquest exemple, veurem com una classe base pot tenir diferents implementacions en les seves subclasses.

class Animal {
    func makeSound() {
        print("Some generic animal sound")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Woof!")
    }
}

class Cat: Animal {
    override func makeSound() {
        print("Meow!")
    }
}

let animals: [Animal] = [Dog(), Cat(), Animal()]

for animal in animals {
    animal.makeSound()
}

Explicació:

  • La classe Animal té un mètode makeSound.
  • Les subclasses Dog i Cat sobreescriuen el mètode makeSound per proporcionar la seva pròpia implementació.
  • Quan iterem sobre la llista d'animals, cada objecte crida el seu propi mètode makeSound.

Polimorfisme Paramètric

El polimorfisme paramètric es pot aconseguir mitjançant l'ús de genèrics en Swift.

func swapValues<T>(a: inout T, b: inout T) {
    let temp = a
    a = b
    b = temp
}

var x = 5
var y = 10
swapValues(a: &x, b: &y)
print("x: \(x), y: \(y)") // x: 10, y: 5

var str1 = "Hello"
var str2 = "World"
swapValues(a: &str1, b: &str2)
print("str1: \(str1), str2: \(str2)") // str1: World, str2: Hello

Explicació:

  • La funció swapValues és genèrica i pot treballar amb qualsevol tipus de dades.
  • Els valors de x i y, així com str1 i str2, es poden intercanviar utilitzant la mateixa funció.

Polimorfisme d'Ad Hoc

El polimorfisme d'ad hoc es pot veure en la sobrecàrrega de mètodes.

class Printer {
    func printValue(_ value: Int) {
        print("Integer value: \(value)")
    }
    
    func printValue(_ value: String) {
        print("String value: \(value)")
    }
}

let printer = Printer()
printer.printValue(42) // Integer value: 42
printer.printValue("Hello") // String value: Hello

Explicació:

  • La classe Printer té dos mètodes printValue amb diferents signatures.
  • El compilador decideix quin mètode cridar basant-se en el tipus de l'argument.

Exercicis Pràctics

Exercici 1: Polimorfisme de Subtipus

Crea una classe base Vehicle amb un mètode move. Després, crea dues subclasses Car i Bicycle que sobreescriguin el mètode move amb la seva pròpia implementació. Finalment, crea una llista de vehicles i crida el mètode move per a cada un d'ells.

Solució:

class Vehicle {
    func move() {
        print("The vehicle is moving")
    }
}

class Car: Vehicle {
    override func move() {
        print("The car is driving")
    }
}

class Bicycle: Vehicle {
    override func move() {
        print("The bicycle is pedaling")
    }
}

let vehicles: [Vehicle] = [Car(), Bicycle(), Vehicle()]

for vehicle in vehicles {
    vehicle.move()
}

Exercici 2: Polimorfisme Paramètric

Crea una funció genèrica compareValues que prengui dos arguments i retorni true si són iguals i false en cas contrari. Prova la funció amb diferents tipus de dades.

Solució:

func compareValues<T: Equatable>(_ a: T, _ b: T) -> Bool {
    return a == b
}

print(compareValues(5, 5)) // true
print(compareValues("Hello", "World")) // false
print(compareValues(3.14, 3.14)) // true

Exercici 3: Polimorfisme d'Ad Hoc

Crea una classe Calculator amb dos mètodes add. Un mètode ha de sumar dos enters i l'altre ha de sumar dos nombres de punt flotant. Prova els mètodes amb diferents tipus de dades.

Solució:

class Calculator {
    func add(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
    
    func add(_ a: Double, _ b: Double) -> Double {
        return a + b
    }
}

let calculator = Calculator()
print(calculator.add(5, 10)) // 15
print(calculator.add(3.14, 2.71)) // 5.85

Conclusió

El polimorfisme és un concepte poderós que permet que el mateix mètode o funció tingui diferents comportaments segons el context. En Swift, es pot aconseguir mitjançant l'ús de classes, protocols, herència i genèrics. Comprendre i aplicar el polimorfisme pot fer que el teu codi sigui més flexible i reutilitzable. En el proper tema, explorarem els protocols, que són una altra eina poderosa per aconseguir el polimorfisme en Swift.

© Copyright 2024. Tots els drets reservats