Static vs Class em Swift: qual escolher para o seu código?

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução: a eterna disputa entre static e class em Swift

\n

Se você já programou em Swift, certamente já se deparou com a seguinte situação: precisa criar um método ou variável que pertence ao próprio tipo, e não à sua instância. E surge o dilema: usar a palavra-chave static ou class? No Stack Overflow, essa pergunta acumulou milhares de visualizações, e não é à toa: a diferença é sutil, mas crucial para o design correto da arquitetura do aplicativo.

\n

Neste tutorial, vamos entender de uma vez por todas as diferenças entre static e class em Swift, quando usar cada um e como não cair em armadilhas com herança. Vamos lá!

\n\n

O que são propriedades e métodos de tipo?

\n

Antes de mergulharmos nos detalhes, vamos relembrar o básico. Em Swift, cada classe, estrutura ou enumeração tem dois tipos de membros:

\n
    \n
  • De instância (instance) — pertencem a um objeto específico. Para usá-los, é preciso criar uma instância: let obj = MyClass().
  • \n
  • De tipo (type) — pertencem ao próprio tipo. São chamados pelo nome do tipo: MyClass.someMethod().
  • \n
\n

Para criar propriedades e métodos de tipo em Swift, usamos as palavras-chave static e class. E é aqui que a coisa fica interessante.

\n\n

Static: rígido e imutável

\n

A palavra-chave static é sua amiga confiável quando você quer criar uma propriedade ou método que não pode ser substituído em uma subclasse. Ela funciona da mesma forma para classes, estruturas e enumerações.

\n

Vamos ver um exemplo. Imagine que estamos criando um aplicativo para registrar estudantes e queremos armazenar o número total de objetos criados:

\n\n
class Student {\n    static var totalCount = 0\n    \n    let name: String\n    \n    init(name: String) {\n        self.name = name\n        Student.totalCount += 1\n    }\n    \n    static func printTotal() {\n        print("Total de estudantes: \\(totalCount)")\n    }\n}\n\nlet s1 = Student(name: "Ivan")\nlet s2 = Student(name: "Maria")\nStudent.printTotal() // Exibe: Total de estudantes: 2
\n\n

Observe que acessamos totalCount e printTotal() pelo nome da classe Student, e não por uma instância. Isso é útil para contadores, configurações padrão ou cache de dados.

\n\n

Static em estruturas e enumerações

\n

Em estruturas e enumerações, static é a única maneira de declarar membros de tipo. Por exemplo:

\n\n
enum HTTPMethod {\n    case get\n    case post\n    case put\n    \n    static let defaultMethod: HTTPMethod = .get\n}\n\nstruct AppConfig {\n    static let apiURL = "https://api.example.com"\n    static let timeout: Double = 30.0\n}
\n\n

Aqui, static funciona perfeitamente, pois estruturas e enumerações não suportam herança e, portanto, não precisam de substituição.

\n\n

Class: flexibilidade com herança

\n

Já a palavra-chave class é uma ferramenta para quem trabalha com classes (e apenas com elas) e deseja permitir que subclasses substituam métodos ou propriedades. class não pode ser usado em estruturas ou enumerações.

\n

Suponha que temos uma classe base Vehicle e queremos que cada subclasse possa fornecer sua própria versão da descrição:

\n\n
class Vehicle {\n    class func description() -> String {\n        return "Isto é um veículo"\n    }\n}\n\nclass Car: Vehicle {\n    override class func description() -> String {\n        return "Isto é um carro"\n    }\n}\n\nclass Bicycle: Vehicle {\n    override class func description() -> String {\n        return "Isto é uma bicicleta"\n    }\n}\n\nprint(Vehicle.description()) // Isto é um veículo\nprint(Car.description())     // Isto é um carro\nprint(Bicycle.description()) // Isto é uma bicic                

Blogs

Book Recommendations