Menu
Coddy logo textTech

Definire i protocolli

Fa parte della sezione Programmazione orientata agli oggetti del percorso Swift di Coddy. Lezione 27 di 57.

Un protocollo elenca dei requisiti (metodi e proprietà) senza implementarli. Un tipo è conforme al protocollo fornendo ogni requisito; a quel punto può essere usato ovunque sia previsto il protocollo:

protocol Describable {
    func describe() -> String
}

struct Book: Describable {
    let title: String
    func describe() -> String { "Book: \(title)" }
}

print(Book(title: "Dune").describe())

Output:

Book: Dune

A differenza dell'ereditarietà, un protocollo funziona allo stesso modo con struct, classi ed enum, e un tipo può conformarsi a molti protocolli. Il protocollo indica solo cosa può fare un tipo; ogni tipo decide come:

protocol Describable {
    func describe() -> String
}

struct Point: Describable {
    var x = 0, y = 0
    func describe() -> String { "(\(x), \(y))" }
}

enum Level: Describable {
    case low, high
    func describe() -> String { self == .low ? "low" : "high" }
}

print(Point(x: 1, y: 2).describe())
print(Level.high.describe())

Output:

(1, 2)
high

I requisiti delle proprietà specificano il tipo e indicano se la proprietà è di sola lettura ({ get }) o anche scrivibile ({ get set }). Un requisito { get } può essere soddisfatto da una proprietà memorizzata o calcolata:

protocol Named {
    var name: String { get }
}

struct User: Named {
    let name: String
}

struct Planet: Named {
    var number: Int
    var name: String { "Planet \(number)" }
}

print(User(name: "ada").name)
print(Planet(number: 3).name)

Output:

ada
Planet 3

Se un tipo dichiara di conformarsi ma non soddisfa un requisito, non viene compilato. Il compilatore verifica ogni conformità, quindi il codice che usa il protocollo può farvi affidamento:

protocol Priced {
    var price: Int { get }
    func discounted(by percent: Int) -> Int
}

// struct Ticket: Priced { var price = 10 }
// errore: il tipo 'Ticket' non è conforme al protocol 'Priced'
challenge icon

Sfida

Facile

Dichiara un protocollo Shape con una proprietà di sola lettura name (String) e un metodo area() che restituisce Double. Fai conformare a esso le struct Rectangle (width, height) e Circle (radius, usando 3.0 per π per mantenere semplici i numeri), con i nomi rectangle e circle.

Il codice fornito legge righe r,3,4 o c,2, crea la forma corrispondente e stampa rectangle: 12.0.

Il tuo codice va in Shape.swift, Rectangle.swift e Circle.swift. main.swift contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

// Codice di input/output fornito: lascialo così com'è
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
    let p = line.split(separator: ",").map(String.init)
    if p[0] == "r" {
        let s = Rectangle(width: Double(p[1])!, height: Double(p[2])!)
        print("\(s.name): \(s.area())")
    } else {
        let s = Circle(radius: Double(p[1])!)
        print("\(s.name): \(s.area())")
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Playground Swift