Swift 라이브러리에서 이러한 정의를 볼 수 있습니다.
extension Bool : BooleanLiteralConvertible {
static func convertFromBooleanLiteral(value: Bool) -> Bool
}
protocol BooleanLiteralConvertible {
typealias BooleanLiteralType
class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}
로 정의 된 멤버 함수 static func
와로 정의 된 다른 멤버 함수의 차이점은 무엇입니까 class func
? 그것은 단순히 static
구조체와 열거의 정적 함수와 class
클래스와 프로토콜을위한 것입니까? 알아야 할 다른 차이점이 있습니까? 구문 자체에서 이러한 차이점을 갖는 이유는 무엇입니까?
답변
정적은 구조체와 열거의 정적 함수, 클래스와 프로토콜의 클래스를위한 것입니까?
이것이 주요 차이점입니다. 다른 차이점은 클래스 함수가 동적으로 디스패치되고 서브 클래스로 대체 될 수 있다는 것입니다.
프로토콜은 클래스 키워드를 사용하지만 프로토콜 구현에서 구조체를 배제하지는 않으며 대신 정적을 사용합니다. 프로토콜을 위해 클래스가 선택되었으므로 정적 또는 클래스를 나타내는 세 번째 키워드가 필요하지 않습니다.
이 주제에 관한 Chris Lattner의 글 :
우리는 구문 통합 (예 : “type”을 키워드로 사용)을 고려했지만 실제로는 단순한 것이 아닙니다. 키워드 “class”와 “static”은 친숙하고 유익합니다 (한 번 + 메소드 작동 방식을 이해 한 후). 정적 메소드를 클래스에 추가 할 수있는 기회를 제공합니다. 이 모델의 가장 이상한 점은 프로토콜이 키워드를 선택해야하고 ( ‘클래스’를 선택한 경우) 균형이 맞아야한다는 것입니다.
다음은 클래스 함수의 재정의 동작 중 일부를 보여주는 스 니펫입니다.
class MyClass {
class func myFunc() {
println("myClass")
}
}
class MyOtherClass: MyClass {
override class func myFunc() {
println("myOtherClass")
}
}
var x: MyClass = MyOtherClass()
x.dynamicType.myFunc() //myOtherClass
x = MyClass()
x.dynamicType.myFunc() //myClass
답변
더 명확하게하기 위해 여기에 예를 들겠습니다.
class ClassA {
class func func1() -> String {
return "func1"
}
static func func2() -> String {
return "func2"
}
/* same as above
final class func func2() -> String {
return "func2"
}
*/
}
static func
~와 같다 final class func
이기 때문에 final
하위 클래스에서 아래와 같이 재정의 할 수 없습니다.
class ClassB : ClassA {
override class func func1() -> String {
return "func1 in ClassB"
}
// ERROR: Class method overrides a 'final` class method
override static func func2() -> String {
return "func2 in ClassB"
}
}
답변
나는 놀이터에서 몇 가지 실험을하고 결론을 얻었습니다.
보시다시피의 경우 또는 class
의 사용 은 습관의 문제입니다.class func
static func
설명이있는 운동장 예 :
class Dog {
final func identity() -> String {
return "Once a woofer, forever a woofer!"
}
class func talk() -> String {
return "Woof woof!"
}
static func eat() -> String {
return "Miam miam"
}
func sleep() -> String {
return "Zzz"
}
}
class Bulldog: Dog {
// Can not override a final function
// override final func identity() -> String {
// return "I'm once a dog but now I'm a cat"
// }
// Can not override a "class func", but redeclare is ok
func talk() -> String {
return "I'm a bulldog, and I don't woof."
}
// Same as "class func"
func eat() -> String {
return "I'm a bulldog, and I don't eat."
}
// Normal function can be overridden
override func sleep() -> String {
return "I'm a bulldog, and I don't sleep."
}
}
let dog = Dog()
let bullDog = Bulldog()
// FINAL FUNC
//print(Dog.identity()) // compile error
print(dog.identity()) // print "Once a woofer, forever a woofer!"
//print(Bulldog.identity()) // compile error
print(bullDog.identity()) // print "Once a woofer, forever a woofer!"
// => "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses.
// CLASS FUNC
print(Dog.talk()) // print "Woof woof!", called directly from class
//print(dog.talk()) // compile error cause "class func" is meant to be called directly from class, not an instance.
print(Bulldog.talk()) // print "Woof woof!" cause it's called from Bulldog class, not bullDog instance.
print(bullDog.talk()) // print "I'm a bulldog, and I don't woof." cause talk() is redeclared and it's called from bullDig instance
// => "class func" is like a "static" one, must be called directly from class or subclassed, can be redeclared but NOT meant to be overridden.
// STATIC FUNC
print(Dog.eat()) // print "Miam miam"
//print(dog.eat()) // compile error cause "static func" is type method
print(Bulldog.eat()) // print "Miam miam"
print(bullDog.eat()) // print "I'm a bulldog, and I don't eat."
// NORMAL FUNC
//print(Dog.sleep()) // compile error
print(dog.sleep()) // print "Zzz"
//print(Bulldog.sleep()) // compile error
print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep."
답변
유형 변수 속성을 선언하려면
static
선언 수정자를 사용하여 선언을 표시하십시오 .class
서브 클래스가 수퍼 클래스의 구현을 재정의하도록 클래스가 선언 수정자를 사용하여 유형 계산 속성을 표시 할 수 있습니다 . 유형 속성은 유형 속성에서 설명합니다.참고
클래스 선언에서, 키워드는static
모두로 선언 표시하는 것과 같은 효과가class
및final
선언 수정합니다.
답변
apple이 발행 한 Swift 2.2 Book에 따르면 :
“ static
방법의 func 키워드 앞에 키워드를 작성하여 유형 방법을 나타냅니다 . 클래스는 또한 class
키워드 를 사용하여 서브 클래스가 수퍼 클래스의 해당 메소드 구현을 대체 할 수있게 합니다.”
답변
Swift2.0에서 Apple은 다음과 같이 말합니다.
“프로토콜에서 정적 키워드를 정의 할 때 항상 접 두부 유형 특성 요구 사항을 지정하십시오.이 규칙은 클래스에 의해 구현 될 때 유형 특성 요구 사항에 클래스 또는 정적 키워드를 접두어로 사용할 수있는 경우에도 적용됩니다.”
답변
이 예는 모든 측면을 지 웁니다!
import UIKit
class Parent {
final func finalFunc() -> String { // Final Function, cannot be redeclared.
return "Parent Final Function."
}
static func staticFunc() -> String { // Static Function, can be redeclared.
return "Parent Static Function."
}
func staticFunc() -> String { // Above function redeclared as Normal function.
return "Parent Static Function, redeclared with same name but as non-static(normal) function."
}
class func classFunc() -> String { // Class Function, can be redeclared.
return "Parent Class Function."
}
func classFunc() -> String { // Above function redeclared as Normal function.
return "Parent Class Function, redeclared with same name but as non-class(normal) function."
}
func normalFunc() -> String { // Normal function, obviously cannot be redeclared.
return "Parent Normal Function."
}
}
class Child:Parent {
// Final functions cannot be overridden.
override func staticFunc() -> String { // This override form is of the redeclared version i.e: "func staticFunc()" so just like any other function of normal type, it can be overridden.
return "Child Static Function redeclared and overridden, can simply be called Child Normal Function."
}
override class func classFunc() -> String { // Class function, can be overidden.
return "Child Class Function."
}
override func classFunc() -> String { // This override form is of the redeclared version i.e: "func classFunc()" so just like any other function of normal type, it can be overridden.
return "Child Class Function, redeclared and overridden, can simply be called Child Normal Function."
}
override func normalFunc() -> String { // Normal function, can be overridden.
return "Child Normal Function."
}
}
let parent = Parent()
let child = Child()
// Final
print("1. " + parent.finalFunc()) // 1. Can be called by object.
print("2. " + child.finalFunc()) // 2. Can be called by object, parent(final) function will be called.
// Parent.finalFunc() // Cannot be called by class name directly.
// Child.finalFunc() // Cannot be called by class name directly.
// Static
print("3. " + parent.staticFunc()) // 3. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("4. " + child.staticFunc()) // 4. Cannot be called by object, this is override form redeclared version (normal function).
print("5. " + Parent.staticFunc()) // 5. Can be called by class name directly.
print("6. " + Child.staticFunc()) // 6. Can be called by class name direcly, parent(static) function will be called.
// Class
print("7. " + parent.classFunc()) // 7. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("8. " + child.classFunc()) // 8. Cannot be called by object, this is override form redeclared version (normal function).
print("9. " + Parent.classFunc()) // 9. Can be called by class name directly.
print("10. " + Child.classFunc()) // 10. Can be called by class name direcly, child(class) function will be called.
// Normal
print("11. " + parent.normalFunc()) // 11. Can be called by object.
print("12. " + child.normalFunc()) // 12. Can be called by object, child(normal) function will be called.
// Parent.normalFunc() // Cannot be called by class name directly.
// Child.normalFunc() // Cannot be called by class name directly.
/*
Notes:
___________________________________________________________________________
|Types------Redeclare------Override------Call by object------Call by Class|
|Final----------0--------------0---------------1------------------0-------|
|Static---------1--------------0---------------0------------------1-------|
|Class----------1--------------1---------------0------------------1-------|
|Normal---------0--------------1---------------1------------------0-------|
---------------------------------------------------------------------------
Final vs Normal function: Both are same but normal methods can be overridden.
Static vs Class function: Both are same but class methods can be overridden.
*/