Menu
Coddy logo textTech

Controle de Acesso

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

Encapsulamento significa que um tipo controla como seus dados podem ser usados. O controle de acesso decide quem pode ver uma propriedade ou método. Marcar um membro como private o oculta de todo o código fora do tipo (e de suas extensões no mesmo arquivo):

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        balance += amount
    }
}

var a = Account()
a.deposit(50)
// a.balance = 1_000_000   // erro: 'balance' é inacessível devido ao nível de proteção 'private'

O código externo pode então usar apenas o que o tipo oferece. O tipo pode verificar cada alteração, portanto seus dados nunca acabam em um estado que o tipo não permite:

struct Account {
    private var balance = 0

    mutating func deposit(_ amount: Int) {
        if amount > 0 { balance += amount }
    }

    func report() -> String {
        "balance: \(balance)"
    }
}

var a = Account()
a.deposit(50)
a.deposit(-999)
print(a.report())

Saída:

balance: 50

O Swift tem cinco níveis de acesso. Sem uma palavra-chave, um membro é internal: visível em todo o mesmo módulo (seu aplicativo ou pacote). Os níveis, do mais aberto ao mais restrito:

open        // outros módulos podem usá-lo e criar subclasses dele (somente classes)
public      // outros módulos podem usá-lo
internal    // padrão: o módulo inteiro
fileprivate // somente este arquivo-fonte
private     // este tipo (e suas extensões no arquivo)

Métodos auxiliares privados mantêm a superfície pública pequena: quem chama vê o que o tipo faz, não como ele faz.

struct Password {
    private let text: String

    init(_ text: String) { self.text = text }

    var isStrong: Bool {
        hasDigit() && text.count >= 8
    }

    private func hasDigit() -> Bool {
        text.contains { $0.isNumber }
    }
}

print(Password("secret123").isStrong)
print(Password("short1").isStrong)

Saída:

true
false
challenge icon

Desafio

Fácil

Complete a estrutura Locker. Seus code e items são private. store(_:code:) adiciona um item somente quando o código corresponde e retorna se isso ocorreu; items(code:) retorna os itens armazenados unidos por , (ou empty) quando o código corresponde, e wrong code caso contrário.

O código fornecido lê o código do armário e, em seguida, os comandos put <code> <item> ou open <code>. Ele imprime stored ou denied para cada put e o resultado para cada open.

Seu código deve ficar em Locker.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) }
var locker = Locker(code: input[0])
for cmd in input.dropFirst() {
    let p = cmd.split(separator: " ").map(String.init)
    if p[0] == "put" {
        print(locker.store(p[2], code: p[1]) ? "stored" : "denied")
    } else {
        print(locker.items(code: p[1]))
    }
}
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