Vai al contenuto

CLASSI

Cosa imparerò:

  • Come creare modelli con le classi
  • Ereditarietà
  • Reference

Le classi sono simili alle struct, e possiamo utilizzarle come le struct per creare nostri tipi di dato, combinando una o più variabili.

Una delle differenze principali dalle struct, è che se non diamo valori di default alle proprietà, sarà d’obbligo la creazione di un init.

class Veicolo {
    var ruote: Int
    init(ruote: Int) {
        self.ruote = ruote
    } 
    func rumore() {
        // Implementazione del metodo rumore
    }
}

La seconda differenza è l’ereditarietà. Ovvero abbiamo la possibilità di ereditare proprietà e metodi da

class Bicicletta: Veicolo {
    var cestino: Bool
    init(ruote: Int, cestino: Bool) {
        self.cestino = cestino
        super.init(ruote: ruote)
    }
    override func rumore() {
        print("Suono della bicicletta")
    }
}

Creando un’istanza di tipo Bicicletta, avremo la possibilità di accedere alla proprietà cestino, ma anche a quelle ereditate da Veicolo ovvero ruote e anche al metodo rumore(), utilizzando la sintassi del punto.

var biciMary = Bicicletta(ruote: 2, cestino: true)
biciMary.rumore()

Output

Suono della bicicletta

Veicolo sarà una classe base perché non eredita da nessuna. Bicicletta è una sottoclasse perché eredita da una superclasse.

class Tandem: Bicicletta {
    var passeggeri: Int
       init(passeggeri: Int) {
        self.passeggeri = passeggeri
        super.init(ruote: 2, cestino: true)
    }
       override func rumore() {
        print("Il tandem non fa rumore")
    }
}

Tandem eredita tutte le proprietà e metodi di Bicicletta ma anche quelli di Veicolo, e possiamo sovrascrivere le proprietà e i metodi ereditati con la keyword override.

Se non diamo un valore di default ad una proprietà all’interno di una sottoclasse dovremo creare un init al cui interno andranno inserite tutte le proprietà anche quelle ereditate, e potremo utilizzare super.init() per richiamare l’inizializzatore delle superclasse. Presupponiamo che la variabile ruote in Veicolo non abbia un valore di default:

class Treno: Veicolo {
    var vapore: Bool
    init(vapore: Bool, ruote: Int) {
        self.vapore = vapore
        super.init(ruote: ruote)
    }
    override func rumore() {
        print("Suono del treno")
    }
}

L’altra sostanziale differenza dalle struct riguarda il fatto che le classi sono reference types. Ovvero quando si assegna un’istanza di una classe a un’altra variabile, non viene creata una copia: entrambe fanno riferimento allo stesso oggetto. Perciò se ne modifichiamo una, andranno ad essere modificate tutte.

var biciMary = Bicicletta(ruote: 2, cestino: false)
var biciJohn = biciMary
biciMary.ruote = 4

Anche le ruote di biciJohn saranno 4, perché faremo riferimento sempre allo stesso oggetto.