Static func vs class func em Swift: guia completo para desenvolvedores
\n\nTodo mundo que programa em Swift, mais cedo ou mais tarde, enfrenta o dilema: static func ou class func? À primeira vista, ambas as palavras-chave servem para criar métodos de nível de tipo. Mas a diferença entre elas não é apenas um capricho sintático, e sim uma diferença fundamental relacionada à herança e ao polimorfismo. Neste artigo, vamos entender de uma vez por todas a diferença entre static func e class func em Swift, quando usar cada um e como esse conhecimento ajuda a escrever um código mais limpo e flexível.
\n\nO que são métodos de tipo em Swift?
\n\nAntes de mergulharmos nas diferenças, vamos relembrar os conceitos básicos. Em Swift, os métodos são divididos em dois tipos:
\n\n- \n
- Métodos de instância (instance methods) — são chamados em um objeto específico de uma classe, struct ou enumeração. \n
- Métodos de tipo (type methods) — são chamados no próprio tipo, e não em sua instância. Para declará-los, usamos as palavras-chave
staticouclass. \n
Os métodos de tipo são ideais para métodos de fábrica, singletons, funções utilitárias e configurações que não estão vinculadas a um estado específico do objeto.
\n\nStatic func: o principal guardião da imutabilidade
\n\nstatic func é um método que não pode ser sobrescrito em uma subclasse. Ele pertence exclusivamente ao tipo no qual foi definido. A palavra-chave static funciona da mesma forma para classes, structs e enumerações.
Exemplo: static func em uma classe
\n\nclass Animal {\n static func describe() {\n print("Sou um animal. Minha essência não pode ser alterada.")\n }\n \n func speak() {\n print("Emito um som")\n }\n}\n\nclass Dog: Animal {\n // Erro! Não é possível sobrescrever um método static\n // override static func describe() { }\n \n override func speak() {\n print("Au au!")\n }\n}\n\n// Uso\nAnimal.describe() // "Sou um animal. Minha essência não pode ser alterada."\nDog.describe() // Também "Sou um animal. Minha essência não pode ser alterada."\n\n\nObserve: Dog.describe() chama o método da classe pai. Embora tecnicamente a subclasse herde o método estático, não é possível sobrescrevê-lo. Esse comportamento é semelhante ao final class func.
Static func em structs
\n\nStructs (value types) também suportam métodos estáticos:
\n\nstruct MathHelper {\n static func square(_ number: Int) -> Int {\n return number * number\n }\n}\n\nlet result = MathHelper.square(5) // 25\n\n\nComo structs não suportam herança, static aqui é a única maneira possível de declarar um método de tipo.
Class func: flexibilidade da herança
\n\nclass func é um método de tipo que pode ser sobrescrito em uma subclasse. Ele está disponível apenas para classes (reference types). Structs e enumerações não podem usar class.
Exemplo: class func e sua sobrescrita
\n\nclass Vehicle {\n class func makeNoise() {\n print("O veículo faz barulho")\n }\n \n class final func isMotorized() -> Bool {\n return true\n }\n}\n\nclass Car: Vehicle {\n override class func makeNoise() {\n print("O carro ronca: vrum vrum!")\n }\n \n // Erro! Não é possível sobrescrever final class func\n // override class func isMotorized() -> Bool { return false }\n}\n\n// Uso\nVehicle.makeNoise() // "O veículo faz barulho"\nCar.makeNoise() // "O carro ronca: vrum vrum!"\n\n\nComo você pode ver, class func se comporta como um método virtual comum, mas é chamado no nível do tipo. Isso abre possibilidades para polimorfismo no nível das classes.