Swift에서 static func와 class func의 차이점은 무엇입니까?
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
및 기능 및 Enum을 위한 것입니다.class
업이나프 로로로? 용용? 용???또알 야이 ?이 이? ?? ??구문 자체에서 이러한 차이를 갖는 근거는 무엇입니까?
좀 더 명확히 하기 위해 예를 하나 들겠습니다.
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
렇기문 because because이다.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"
}
}
스태틱은 구조 및 Enum의 정적 기능, 클래스는 클래스 및 프로토콜에 대한 정적 기능뿐입니까?
그게 가장 큰 차이점이에요.다른 차이점은 클래스 함수가 동적으로 디스패치되어 서브클래스에 의해 덮어쓸 수 있다는 것입니다.
프로토콜은 class 키워드를 사용하지만 프로토콜 구현에서 구조체를 제외하지 않고 대신 정적만 사용합니다.static 또는 클래스를 나타내기 위해 세 번째 키워드가 필요하지 않도록 프로토콜로 클래스를 선택했습니다.
Chris Latner가 이 토픽을 소개합니다.
구문(키워드로서 「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
의, " " " "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
선언 수식자
출처: Swift Programming Language - 유형 변수 속성
static 키워드와 class 키워드를 모두 사용하면 메서드를 클래스의 인스턴스가 아닌 클래스에 부가할 수 있습니다.예를 들어 이름 및 연령과 같은 속성을 사용하여 Student 클래스를 만든 다음 개별 인스턴스가 아닌 Student 클래스 자체에서 소유하는 정적 메서드 numberOfStudents를 만들 수 있습니다.
스태틱과 클래스는 상속을 지원하는 방법이 다릅니다.정적 메서드를 만들면 해당 메서드는 클래스가 소유하게 되어 하위 클래스에서 변경할 수 없지만 클래스를 사용하면 필요에 따라 재정의될 수 있습니다.
다음은 코드 예시입니다.
class Vehicle {
static func getCurrentSpeed() -> Int {
return 0
}
class func getCurrentNumberOfPassengers() -> Int {
return 0
}
}
class Bicycle: Vehicle {
//This is not allowed
//Compiler error: "Cannot override static method"
//static override func getCurrentSpeed() -> Int {
//return 15
//}
class override func getCurrentNumberOfPassengers() -> Int {
return 1
}
}
이 예에서는 모든 측면이 지워집니다.
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.
*/
출력:
애플이 발간한 스위프트 2.2 북에 따르면:
"유형 메서드는 다음과 같이 적습니다.static
키워드를 지정합니다.클래스에서는,class
서브클래스가 해당 메서드의 슈퍼클래스의 구현을 덮어쓸 수 있도록 하는 키워드입니다.
Swift 2.0부터 Apple은 다음과 같이 말합니다.
"프로토콜에서 속성을 정의할 때는 항상 static 키워드를 사용하여 접두사 유형 속성 요구사항을 지정하십시오.이 규칙은 유형 속성 요건을 클래스에 의해 구현될 때 class 키워드 또는 static 키워드로 프리픽스할 수 있는 경우에도 관련됩니다."
이것은 type 메서드라고 불리며 인스턴스 메서드와 같이 닷 구문을 사용하여 호출됩니다.단, 유형 메서드는 해당 유형의 인스턴스가 아닌 유형으로 호출합니다.SomeClass라는 클래스의 유형 메서드를 다음과 같이 호출합니다.
언급URL : https://stackoverflow.com/questions/25156377/what-is-the-difference-between-static-func-and-class-func-in-swift
'bestsource' 카테고리의 다른 글
클래스별 유니코드 문자 목록은 어디서 얻을 수 있나요? (0) | 2023.04.24 |
---|---|
ADT에는 'org.eclipse'가 필요합니다.wst.sse.core 0.0.0'을 찾을 수 없습니다. (0) | 2023.04.24 |
프로그래밍 방식으로 버튼을 만들려면 어떻게 해야 합니다. (0) | 2023.04.24 |
Windows 7 x 64에서는 Git Bash가 매우 느리다 (0) | 2023.04.19 |
WPF 트리 표시:탐색기와 같이 모서리가 둥근 항목을 스타일링하는 방법 (0) | 2023.04.19 |