Static func vs class func en Swift: guía completa para desarrolladores
\n\nCualquiera que escriba en Swift, tarde o temprano se enfrenta al dilema: static func o class func? A primera vista, ambas palabras clave sirven para crear métodos a nivel de tipo. Pero la diferencia entre ellas no es un capricho sintáctico, sino una distinción fundamental relacionada con la herencia y el polimorfismo. En este artículo, aclararemos de una vez por todas en qué se diferencia static func de class func en Swift, cuándo usar cada uno y cómo este conocimiento ayudará a escribir código más limpio y flexible.
\n\n¿Qué son los métodos de tipo en Swift?
\n\nAntes de sumergirnos en las diferencias, recordemos los conceptos básicos. En Swift, los métodos se dividen en dos tipos:
\n\n- \n
- Métodos de instancia (instance methods) — se invocan en un objeto específico de una clase, estructura o enumeración. \n
- Métodos de tipo (type methods) — se invocan en el propio tipo, no en su instancia. Para declararlos se utilizan las palabras clave
staticoclass. \n
Los métodos de tipo son ideales para métodos de fábrica, singletons, funciones utilitarias y configuraciones que no están vinculadas a un estado específico del objeto.
\n\nStatic func: el principal guardián de la inmutabilidad
\n\nstatic func es un método que no puede ser sobrescrito en una subclase. Pertenece exclusivamente al tipo en el que se define. La palabra clave static funciona igual para clases, estructuras y enumeraciones.
Ejemplo: static func en una clase
\n\nclass Animal {\n static func describe() {\n print("Soy un animal. Mi esencia no se puede cambiar.")\n }\n \n func speak() {\n print("Emito un sonido")\n }\n}\n\nclass Dog: Animal {\n // ¡Error! No se puede sobrescribir un método static\n // override static func describe() { }\n \n override func speak() {\n print("¡Guau-guau!")\n }\n}\n\n// Uso\nAnimal.describe() // "Soy un animal. Mi esencia no se puede cambiar."\nDog.describe() // También "Soy un animal. Mi esencia no se puede cambiar."\n\n\nObserve: Dog.describe() llama al método de la clase padre. Aunque técnicamente la subclase hereda el método estático, no se puede sobrescribir. Este comportamiento se asemeja a final class func.
Static func en estructuras
\n\nLas estructuras (value types) también admiten 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\nDado que las estructuras no admiten herencia, static aquí es la única forma posible de declarar un método de tipo.
Class func: flexibilidad de herencia
\n\nclass func es un método de tipo que se puede sobrescribir en una subclase. Está disponible solo para clases (reference types). Las estructuras y enumeraciones no pueden usar class.
Ejemplo: class func y su sobrescritura
\n\nclass Vehicle {\n class func makeNoise() {\n print("El vehículo hace ruido")\n }\n \n class final func isMotorized() -> Bool {\n return true\n }\n}\n\nclass Car: Vehicle {\n override class func makeNoise() {\n print("El coche zumba: ¡brrrr!")\n }\n \n // ¡Error! No se puede sobrescribir final class func\n // override class func isMotorized() -> Bool { return false }\n}\n\n// Uso\nVehicle.makeNoise() // "El vehículo hace ruido"\nCar.makeNoise() // "El coche zumba: ¡brrrr!"\n\n\nComo puede ver, class func se comporta como un método virtual normal, pero se invoca a nivel de tipo. Esto abre posibilidades para el polimorfismo a nivel de clases.