В чем разница между class func и static func в Swift
Что проверяют
Понимаете ли вы, как в Swift устроены методы типа и как они ведут себя при наследовании. Следом обычно спрашивают, что будет с class var и можно ли написать class в структуре или протоколе.
Как отвечать
Оба модификатора объявляют метод типа: он вызывается на самом типе, Animal.sound(), а не на экземпляре. Разница в одном: можно ли его переопределить.
static func: метод типа, который нельзя переопределить. В классеstaticпо смыслу равенfinal class. Работает в классах, структурах, перечислениях и акторах;class func: метод типа, который подкласс переопределяет черезoverride class func. Существует только в классах, вstructиenumэто ошибка компиляции;- наследование: статический метод подкласс наследует,
Dog.sound()вызовется и вернёт реализацию родителя. Запрещено только переопределение; - диспетчеризация: вызов
staticкомпилятор связывает статически,class funcидёт через таблицу методов класса. Разница видна при вызове через метатип:type(of: pet).sound()дляclass funcвыберет реализацию реального подкласса; - свойства:
static letиstatic varбывают хранимыми, аclass varтолько вычисляемым. Хранимое свойство класса пишется черезstatic; - протоколы: требование объявляется как
static func, а класс может выполнить его черезclass func, если хочет оставить подклассам право на своё поведение.
Практическое правило: static по умолчанию, class только там, где подклассу действительно нужна своя реализация, например фабричный метод или настройка в иерархии контроллеров.
Где спотыкаются
Говорят, что статический метод «не наследуется». Он наследуется и вызывается на подклассе, нельзя лишь подменить реализацию.
Пытаются написать class func в структуре или объявить хранимое class var count = 0. Компилятор это не пропустит и предложит static.
Путают методы типа с методами экземпляра: обращаются к self.name внутри static func. Внутри метода типа self указывает на сам тип, а не на объект.