#Les structures de données

#Classes

Les classes sont des structures fondamentales en programmation orientée objet (OOP) dans Swift. Elles permettent de regrouper des données et des fonctionnalités associées. Une classe est comme un modèle pour créer des objets. Les objets sont des instances de classes, et ils peuvent avoir des propriétés (variables) et des méthodes (fonctions) spécifiques à la classe.

Exemple en Swift :

class Person {
    var name: String = ""
    var age: Int = 0

    func greet() {
        print("Hello, I'm \(name)!")
    }
}

// Utilisation de la classe
let person1 = Person()
person1.name = "John"
person1.age = 25
person1.greet()

#Comment initialiser une classe ?

Une classe peut avoir un constructeur qui est appelé lors de la création d’une instance de la classe. En Swift, le constructeur est appelé init.

Exemple en Swift :

class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func greet() {
        print("Hello, I'm \(name)!")
    }
}

// Utilisation de la classe
let person1 = Person(name: "John", age: 25)
person1.greet()

#Heritage

L’héritage permet de créer une classe qui hérite des propriétés et des méthodes d’une autre classe. La classe qui hérite est appelée subclass (sous-classe) et la classe dont elle hérite est appelée superclass (super-classe). Une sous-classe peut ajouter ses propres propriétés et méthodes, et peut également modifier les propriétés et méthodes de la super-classe.

// Déclaration d'une classe de base (parent)
class Vehicle {
    var brand: String
    
    init(brand: String) {
        self.brand = brand
    }
    
    func start() {
        print("Le véhicule démarre.")
    }
}

// Déclaration d'une classe dérivée (enfant) qui hérite de Vehicle
class Car: Vehicle {
    var model: String
    
    init(brand: String, model: String) {
        self.model = model
        // Appel du constructeur de la classe de base
        super.init(brand: brand)
    }
    
    func drive() {
        print("La voiture \(brand) \(model) est en mouvement.")
    }
}

// Utilisation des classes
let myCar = Car(brand: "Toyota", model: "Camry")
myCar.start() // Utilisation de la méthode héritée de la classe de base
myCar.drive() // Utilisation de la méthode spécifique à la classe dérivée

#Structs

Les structs (structures) sont similaires aux classes. Les structs sont souvent utilisées pour représenter des types de données simples.

Une structure est immutable par nature, c’est un value type (type de valeur). Cela signifie que lorsqu’une structure est assignée à une variable ou passée en paramètre à une fonction, elle est copiée.

Exemple en Swift :

struct Point {
    var x: Int
    var y: Int
}

// Utilisation de la struct
var point1 = Point(x: 10, y: 20)
var point2 = point1
point2.x = 30

print("point1: \(point1.x), \(point1.y)") // Affiche "point1: 10, 20"
print("point2: \(point2.x), \(point2.y)") // Affiche "point2: 30, 20"

#Enum

Les énumérations (enum) sont utilisées pour définir un groupe de valeurs nommées. Elles permettent de rendre le code plus lisible et évitent l’utilisation de valeurs “magiques”. Les cas d’une énumération peuvent avoir des valeurs associées.

enum Direction {
    case north
    case south
    case east
    case west
}

// Utilisation de l'enum
let currentDirection = Direction.north

#Protocols

Les protocoles sont des listes de méthodes et de propriétés que les types peuvent adopter. Ils définissent une interface que les classes, structs ou enums peuvent conformer. Les protocoles permettent de définir des comportements communs sans imposer une hiérarchie de classes spécifique.

Exemple en Swift :

protocol CanFly {
    func fly()
}

class Bird: CanFly {
    func fly() {
        print("The bird is flying!")
    }
}

// Utilisation du protocole
let bird = Bird()
bird.fly()

#Extensions

Les extensions permettent d’ajouter de nouvelles fonctionnalités à un type existant, même si le type n’a pas été déclaré par vous. Cela facilite l’ajout de fonctionnalités à des classes, structs ou enums sans avoir à les modifier directement.

Exemple en Swift :

extension Int {
    func square() -> Int {
        return self * self
    }
}

// Utilisation de l'extension
let number = 5
let squaredNumber = number.square() // squaredNumber est maintenant 25