본문 바로가기

iOS/Swift

Swift) static? class? 메서드 완벽 정복하기

 

 

 

안녕하세요 :))) 소들입니다!!!!

저번 포스팅에서 프로퍼티의 종류와 특징에 대해 다 공부 해봤어요!

프로퍼티 종류엔 저장 프로퍼티, 연산 프로퍼티, 타입 프로퍼티에 대해 알아봤져!?

프로퍼티를 모르면 이번 포스팅을 이해하기가 힘들 것 같아 먼저 공부하시는 것을 ..춫..천..

 

이번엔 프로퍼티와 같이 구조체, 클래스를 만들어가는 멤버인

"메서드" 종류에 대해서 알아볼 거예요 :)

함수 선언 앞에 static, class 붙었다고 겁먹을 거 하나 없음

 

알고보면 간단하고 쉬운 내용이지만, 제대로 공부하지 않으면 나중에 헷갈리니

한번 공부할 때 확실하게 끝내버립시닷!!!

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 함수 vs 메서드

 

후움... 기본에 대해 먼저 짚고 가겠음!!!

혹여나 용어가 어려울 iOS 병아리를 위해 내 포스팅 발췌좀 해오겠음

 

자, 먼저 우리가 일반적으로

func이라는 키워드로 생성하는 것은 모~~두 "함수"

 

 

func doSomething() {
    print("Somaker")
}

 

 

당연히 doSomething이란 것은

func 키워드로 생성한 함수

 

그럼 메서드는 뭐냐??

 

클래스, 구조체, 열거형 속에 포함되어 있는 "함수"

 

를 말함!!!!  만약 우리가 func으로 선언한 함수

클래스, 구조체, 열거형 속에 속해 포함되어 있다면

 

 

class Sodeul {
    func doSomething() {
        print("Somaker")
    }
}

 

 

 

이땐 doSomething을 함수가 아니라 메서드라고 표현함!!!!!!!

 

근데 iOS 앱을 개발하면 보통 함수를 독단적으로 쓸 일은 거~~~~의 없고

클래스나 구조체 내에서 사용하는 경우가 거의 대부분이기 때문에

메서드라는 것이 자연스러울텐데, 메서드보다 큰 범주가 함수임!

 

 

발췌 끝!!!!

이제 함수와 메서드의 차이점에 대해 알았음!!

근데, 이 메서드라는 것은 총 두가지 모습을 가지고 있음!!

 

인스턴스 메서드 (Instance Method)

타입 메서드 (Type Method)

 

어랏?? 우린 이전에 Type Property에 대해 공부 했음!!

Instance가 생성되든 말든 상관 없이, 오로지 해당 "형식(Type)"에 속한 프로퍼티였잖음??

따라서 호출하는 방식도 달랐구!! 메서드 또한 마찬가지라고 생각하면 됨!!!!

 

 

 

 

2. 인스턴스 메서드 (Instance Method)

 

인스턴스와 연관된 메서드로 , "인스턴스를 생성해야만" 호출이 가능하다

 

이름이 어렵다고 겁 먹을 거 하나 없음

먼 솔이냐면 여러분이 지금껏 아~~무렇지 않게 선언해온 메서드들은 모두

"인스턴스 메서드" 였떤 것임

 

 

class Sodeul {
    func doSomething() {
        print("Somaker")
    }
}

 

 

이렇게 아무런 수식어 없이 func으로 시작하는 메서드

모~두 인스턴스 메서드인 것임!!!!

 

 

2-1. 인스턴스 메서드를 호출하는 방법

 

자, 우린 지금껏 저 위의 예제  doSomething을 호출할 때 어떻게 했음!?

 

 

let sodeulSodeul = .init()
sodeul.doSomething()

 

 

이렇게 sodeul이란 "인스턴스를 먼저 생성"하고,

생성된 인스턴스에 .(dot) 문법을 통해 메서드에 접근해왔잖음!!??

이 자연스러운 것이 바로 인스턴스 메서드임!!

 

인스턴스를 생성해야만 호출할 수 있는, 인스턴스에 연관된 메서드!

자, 정리하자면

 

인스턴스 메서드는 "인스턴스"와 연관된 메서드이기 때문에,

"인스턴스를 생성해야만" 해당 인스턴스를 통해 메서드에 접근할 수 있으며,

아무런 수식어 없이 func으로 선언된 메서드는 모두 인스턴스 메서드이다

 

어렵지 않죠 :)

그럼 뭔가 타입 메서드는, 수식어가 붙고 인스턴스를 통해 호출하지 않을 것 같은 느낌이 오지 않나연?!

 

 

 

 

3. 타입 메서드 (Type Method)

 

형식(Type)에 연관된 메서드로, 인스턴스 생성 없이 형식(Type) 이름만 알면 호출이 가능하다

메서드 선언 시 func이란 키워드 앞에 static 혹은 class가 붙으면, 그 메서드는 타입 메서드이다

 

Type Property와 똑~~ 같음!!!!

형식(Type)에 연관된 메서드라서, 인스턴스와는 누구세요? 사이인 거임

무슨 말이냐면, 타입 메서드는 좀이따 자세히 알아볼 것이지만,

func이란 키워드 앞에 static 혹은 class가 붙은 메서드를 타입 메서드라고 하는데,

 

 

class Sodeul {
    static func sayHello() {
        print("Hello")
    }
    class func sayBye() {
        print("Bye")
    }
}

 

 

따라서 위에서 sayHello, sayBye 메서드는 모두 타입 메서드임

 

 

 

2-1. 타입 메서드를 호출하는 방법

 

근데 이 타입 메서드들은 누누히 말하지만 인스턴스와는 전~혀 상관 없는 사이이고,

오로지 "Sodeul"이라는 "Type"에만 연관되어 있는 놈임!!!

 

따라서 호출할 때 어떻게 하냐면, Sodeul이란 Type 이름에 대고 함

 

 

Sodeul.sayHello()
Sodeul.sayBye()

 

 

이렇게!! 인스턴스 메서드가 아니기 때문에, 인스턴스를 생성할 필요 1도 없고,

오로지 내가 속해있는 Type의 이름인 Sodeul만 알면, Sodeul에 대고 메서드를 호출 해버리는 것임!!

 

 

자, 그럼 이제 마지막 궁금증 :)

static과 class의 차이점이 무엇일까!?

 

 

 

2-2. static vs class

 

타입 메서드를 선언하기 위해선 func 앞에 static 혹은 class를 붙여주면 된다고 했음!

그럼 언제 static을 쓰고, 언제 class를 쓸까염!?!?

이 둘을 구분 짓는 것은 메서드 오버라이딩(override)의 여부임!!! 

 

 

 ① static : 오버라이딩을 금지한다! 

 

static은 Subclass에서 해당 타입 메서드를 오버라이딩 하는 것을 금지❌

따라서, 

 

 

class Sodeul {
    static func sayHello() {
        print("Hello")
    }
}
 
class SodeulSodeulSodeul {
    override static func sayHello() {    //Cannot override static method   
    }
}
 

 

 

이렇게 static으로 선언된 타입 메서드 sayHello같은 경우,

Subclass에서 override 하려고 하면 static method는 오버라이딩 안돼! 하고 에러가 남!!

 

 

 

 ② class : 오버라이딩을 허용한다! 

 

class는 Subclass에서 해당 타입 메서드를 오버라이딩 하는 것 허용⭕️

따라서, 

 

class Sodeul {
   class func sayBye() {
        print("Bye")
    }
}
 
class SodeulSodeulSodeul {
    override class func sayBye() {     
    }
}
 

 

 

이렇게 class으로 선언된 타입 메서드 sayBye같은 경우,

Subclass에서 오버라이딩 해도 에러가 발생하지 않음 :)

 

 

 

 

3. 타입 메서드와 인스턴스 메서드의 멤버 접근 범위

 

자, 프로퍼티의 종류엔

 

일반 프로퍼티 (저장 프로퍼티 & 연산 프로퍼티)

타입 프로퍼티 (저장 타입 프로퍼티 & 연산 타입 프로퍼티)

 

가 있었음!!!!

 

 

class Sodeul {
    let name = "Sodeul"                 // 저장 프로퍼티
    static let alias = "SodeulSodeul"   // 저장 타입 프로퍼티
}
 

 

 

그렇다면 이렇게 "name"이란 저장 프로퍼티가 있고 "alias"란 저장 타입 프로퍼티가 있을 때,

인스턴스 메서드와 타입 메서드 모두 이 둘을 모두 사용할 수 있을까?

(프로퍼티에 한정 지었지만, 메서드도 같이 볼 것임)

 

 

 

3-1. 타입 메서드에서는 타입 멤버(프로퍼티&메서드)만 사용 가능하고, 같은 타입 멤버는 타입 이름 없이 접근 가능하다

 

제목(?)에서도 써놨듯이, 오로지 저장 타입 프로퍼티인 alias만 사용할 수 있고,

저장 프로퍼티인 name은 인스턴스 멤버라서 사용할 수 없음

 

 

class Sodeul {
    let name = "Sodeul"               
    static let alias = "SodeulSodeul"  
 
    static func sayHello() {
        print(name)              // error! Instance member 'name' cannot be used on type 'Sodeul
        print(alias)
    }
}
 

 

 

왜냐? 생각해보면 당연함

일반 저장 프로퍼티인 name은 인스턴스 멤버

따라서, 인스턴스가 생성될 때마다 메모리에 올라가는 "인스턴스와 연관된" 프로퍼티

 

하지만 타입 메서드는 "인스턴스를 선언할 필요 없는" 메서드 이기 때문에,

자기랑 똑같이 "인스턴스를 생성할 필요 없는" 타입 프로퍼티의 경우,"같은 타입에 한해 타입 이름 없이도 접근"이 가능하지만,

인스턴스가 생성 되어야만 저장 공간을 갖는 인스턴스 멤버(프로퍼티, 메서드)엔 접근할 수 없는 것임!!

 

 

 

3-2. 인스턴스 메서드에서는 인스턴스 멤버(프로퍼티&메서드)를 사용할 수 있고, 타입 멤버도 타입만 알면 접근 가능하다

 

반대로, "인스턴스를 생성해야만 접근할 수 있는" 인스턴스 메서드에선

인스턴스 멤버인 name엔  당연히 접근 가능하고(인스턴스 생성 됐으니 해당 인스턴스의 name도 메모리에 올라감)

"인스턴스와 상관 없는" 타입 멤버(프로퍼티&메서드)에 접근 시, 기존 방식과 같이 타입 이름을 통해서 접근할 수 있음!!!

 

 

class Sodeul {
    let name = "Sodeul"                
    static let alias = "SodeulSodeul"  
 
    func sayHello() {
        print(name)            
        print(Sodeul.alias)
    }
}
 

 

 

이렇게!!!!

 

 

 

 

 

 

 

 

 

.

.

.

흠 이번엔 헷갈리기 쉬운 메서드 종류에 대해 정리해 봤는데..

저는 포스팅하며 완벽하게 정리가 됐는데 이걸 보시는 분들이 완벽하게 됐을지는..ㅠㅠㅠ

혹시 이해가 안 가시는 부분, 설명이 더 필요한 부분, 잘못된 부분, 피드백

언제나 댓글 남겨주세요~~!!!!!! :)

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday