Menu
Coddy logo textTech

Definindo Protocolos

Parte da seção Programação Orientada a Objetos do Journey de Swift da Coddy. Lição 27 de 57.

Um protocolo lista requisitos (métodos e propriedades) sem implementá-los. Um tipo está em conformidade com o protocolo ao fornecer todos os requisitos e, então, pode ser usado onde quer que o protocolo seja esperado:

protocol Describable {
    func describe() -> String
}

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

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

Saída:

Book: Dune

Ao contrário da herança, um protocolo funciona igualmente para structs, classes e enums, e um tipo pode estar em conformidade com vários protocolos. O protocolo apenas diz o que um tipo pode fazer; cada tipo decide como:

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())

Saída:

(1, 2)
high

Os requisitos de propriedades especificam o tipo e se a propriedade é somente leitura ({ get }) ou também pode ser escrita ({ get set }). Um requisito { get } pode ser atendido por uma propriedade armazenada ou computada:

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)

Saída:

ada
Planet 3

Se um tipo afirma estar em conformidade, mas não atende a um requisito, ele não compila. O compilador verifica cada conformidade, portanto o código que usa o protocolo pode confiar nisso:

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

// struct Ticket: Priced { var price = 10 }
// erro: o tipo 'Ticket' não está em conformidade com o protocolo 'Priced'
challenge icon

Desafio

Fácil

Declare um protocolo Shape com uma propriedade somente leitura name (String) e um método area() que retorne Double. Faça com que as structs Rectangle (width, height) e Circle (radius, usando 3.0 para π para manter os números simples) estejam em conformidade com ele, com os nomes rectangle e circle.

O código fornecido lê linhas r,3,4 ou c,2, cria a forma correspondente e imprime rectangle: 12.0.

Seu código deve ficar em Shape.swift, Rectangle.swift e Circle.swift. main.swift contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

// Código de entrada/saída fornecido: mantenha-o como está
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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Swift