Следующий код компилируется в Swift 1.2:
class myClass {
static func myMethod1() {
}
class func myMethod2() {
}
static var myVar1 = ""
}
func doSomething() {
myClass.myMethod1()
myClass.myMethod2()
myClass.myVar1 = "abc"
}
В чем разница между функцией static и функцией class? Какой я должен использовать, и когда?
Если я попытаюсь определить другую переменную class var myVar2 = ""
, она говорит:
Сохраненные свойства класса, еще не поддерживаемые в классах; вы имели в виду "статический"?
Когда эта функция поддерживается, какая разница будет между переменной static и переменной class (т.е. когда оба определены в классе)? Какой я должен использовать, и когда?
(Xcode 6.3)
static
и class
связывают метод с классом, а не экземпляр класса. Разница заключается в том, что подклассы могут переопределять методы class
; они не могут переопределить методы static
.
class
свойства будут теоретически функционировать одинаково (подклассы могут их переопределять), но они еще не доступны в Swift.
final class
функцией final class
и «статической» функцией внутри класса?
final
может использоваться для отсечки дальнейших переопределений при использовании в подклассе. Оба имеют свое место, я бы сказал, что использование static
или final
при использовании в функции класса тривиально и зависит от вашего стиля.
Я попробовал ответ mipadi и комментарии на детской площадке. И подумал об этом. Ну вот. Я думаю, что ответ mipadi должен быть отмечен как принятый.
class A{
class func classFunction(){
}
static func staticFunction(){
}
class func classFunctionToBeMakeFinalInImmediateSubclass(){
}
}
class B: A {
override class func classFunction(){
}
//Compile Error. Class method overrides a 'final' class method
override static func staticFunction(){
}
//Lets avoid the function called 'classFunctionToBeMakeFinalInImmediateSubclass' being overriden by subclasses
/* First way of doing it
override static func classFunctionToBeMakeFinalInImmediateSubclass(){
}
*/
// Second way of doing the same
override final class func classFunctionToBeMakeFinalInImmediateSubclass(){
}
//To use static or final class is choice of style.
//As mipadi suggests I would use. static at super class. and final class to cut off further overrides by a subclass
}
class C: B{
//Compile Error. Class method overrides a 'final' class method
override static func classFunctionToBeMakeFinalInImmediateSubclass(){
}
}
Что касается ООП, ответ слишком прост:
Подклассы могут переопределять методы class, но не могут переопределять методы static.
В дополнение к вашему сообщению, если вы хотите объявить переменную class (например, вы сделали class var myVar2 = ""
), вы должны сделать это следующим образом:
class var myVar2:String {
return "whatever you want"
}
Я получил эту путаницу в одном из моих проектов, и нашел этот пост, очень полезный. Пробовал то же самое на моей детской площадке, и вот резюме. Надеюсь, это поможет кому-то с сохраненными свойствами и функциями типа static
, final
, class
, переопределением классов vars и т.д.
class Simple {
init() {print("init method called in base")}
class func one() {print("class - one()")}
class func two() {print("class - two()")}
static func staticOne() {print("staticOne()")}
static func staticTwo() {print("staticTwo()")}
final func yesFinal() {print("yesFinal()")}
static var myStaticVar = "static var in base"
//Class stored properties not yet supported in classes; did you mean 'static'?
class var myClassVar1 = "class var1"
//This works fine
class var myClassVar: String {
return "class var in base"
}
}
class SubSimple: Simple {
//Successful override
override class func one() {
print("subClass - one()")
}
//Successful override
override class func two () {
print("subClass - two()")
}
//Error: Class method overrides a 'final' class method
override static func staticOne() {
}
//error: Instance method overrides a 'final' instance method
override final func yesFinal() {
}
//Works fine
override class var myClassVar: String {
return "class var in subclass"
}
}
И вот образцы тестирования:
print(Simple.one())
print(Simple.two())
print(Simple.staticOne())
print(Simple.staticTwo())
print(Simple.yesFinal(Simple()))
print(SubSimple.one())
print(Simple.myStaticVar)
print(Simple.myClassVar)
print(SubSimple.myClassVar)
//Output
class - one()
class - two()
staticOne()
staticTwo()
init method called in base
(Function)
subClass - one()
static var in base
class var in base
class var in subclass
Тестирование в Swift 4 показывает разницу в производительности в симуляторе. Я создал класс с "класс func" и struct with "static func" и запускал их в тесте.
static func:
Однако, запуск того же кода на iPhone 7 под iOS 10.3 показывает точно такую же производительность.
Вот пример проекта в Swift 4 для Xcode 9, если вы хотите испытать себя https://github.com/protyagov/StructVsClassPerformance
Там еще одна разница. class
может использоваться для определения свойств типа только для расчетного типа. Если вам требуется хранимое свойство типа, используйте static
.