![Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티]](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
메서드(Method)
Class
(클래스), Struct
(구조체), Enum
(열거형)에 포함되어있는 '함수'를 메서드라고 한다.
메서드는 다른 말로 클래스 함수라고도 한다.
Struct
는 내부에 함수를 가질 수 있으며, 이러한 함수는 필요에 따라 구조체의 프로퍼티를 사용할 수 있다. 구조체 내부의 함수는 methods
라고하지만 동일한 func
키워드를 사용한다.
클래스, 구조체 및 열거형은 특정 작업이나 기능을 캡슐화한 인스턴스 메서드에 타입 자체와 관련된 타입 메서드를 정의할 수 있다.
class Person { //이 메서드는 person 타입에만 작동(적용)됩니다. func personGreeting() { greet(yourName: "Santosh", category: .Person) } }
클래스 안에 작성되는 함수는 이제 무조건 메서드가 된다.
func someFunction { //함수 구현부 } class someClass { func someMethod { //메서드 구현부 } }
인스턴스 메서드 Instance Methods
인스턴스 메서드는 특정 Class
, Struc
또는 Enum
의 인스턴스에 속하는 함수이다. 인스턴스 프로퍼티의 접근 및 수정 방법 등을 제공하거나 인스턴스의 목적과 관련된 기능을 제공, 해당 인스턴스의 기능을 지원한다.
인스턴스 메서드는 함수와 달리 특정 타입 내부 { }
에 인스턴스 메서드를 작성한다. 따라서 인스턴스가 존재할 때만 사용 가능하다. 기존의 인스턴스가 없으면 호출 불가능하다.
- 인스턴스 메서드가 속한 타입의 여는 중괄호
{
와 닫는 중괄호}
안에 인스턴스 메서드를 작성 - 인스턴스 메서드는, 다른 모든 인스턴스 메서드 및 해당 타입의 특성에 암시적으로(implicit) 접근
- 인스턴스 메서드는 자신이 속한 타입의 특정 인스턴스에서만 호출될 수 있음
class Counter { var count = 0 func increment() { count += 1 } func increment(by amount: Int) { count += amount } func reset() { count = 0 } }
Counter
라는 클래스를 정의했고, Counter 클래스
는 3가지 인스턴스 메서드를 정의하고 있다.
increment()
는 카운터를 1씩 증가시킨다.increment(By: Int)
는 지정된 정수만큼 카운터를 증가시킨다.reset()
은 카운터를 0으로 재설정한다.
프로퍼티와 마찬가지로 .
을 통해 인스턴스 메서드를 호출할 수 있다.
let counter = Counter()// count = 0 (기본값) counter.increment()//count = 1 counter.increment(by: 5)//count = 6 counter.reset()//count = 0
City
라는 구조체를 만들고, population
에는 도시에 얼마나 많은 사람이 있는지 저장하는 프로퍼티와 인구수에 1000
을 곱한 값을 반환하는 collectTaxes()
메서드가 있다고 가정하면
이 메서드는 City
에 속하기 때문에 현재 도시의 인구 프로퍼티를 읽을 수 있게 된다.
struct City { var population: Int func collectTaxes() -> Int { return population * 1000 } }
이 메서드는 구조체에 속하므로 다음과 같이 구조체의 인스턴스에서 호출한다.
let London = City(population: 9_000_000) london.collectTaxes() //9000000000
또 다른 예제를 보자면, 클래스의 인스턴스 메서드에 대한 코드이다.
class LevelClass { var level: Int = 0 { //저장 프로퍼티 //값이 변경되면 실행될 프로퍼티 옵저버 didSet { print("현재 레벨: Lv.\(level)") } } func levelUp() { print("레벨업!") level += 1 } func levelDown() { print("레벨 다운") level -= 1 if level < 0 { reset() } } func jumpLevel(to: Int) { print("레벨이 \(to)로 점프 되었습니다.") level = to } func reset() { print("레벨이 초기화 됩니다.") level = 0 print("레벨이 Lv.\(level)으로 초기화 되었습니다.") } } var levelClassInstance: LevelClass = LevelClass() levelClassInstance.levelUp() //레벨업! //현재 레벨: Lv.1 levelClassInstance.levelDown() //레벨 다운 //현재 레벨: Lv.0 levelClassInstance.levelDown() //레벨 다운 //현재 레벨: Lv.-1 //레벨이 초기화 됩니다. //현재 레벨: Lv.0 //레벨이 Lv.0으로 초기화 되었습니다. levelClassInstance.jumpLevel(to: 20) //레벨이 20로 점프 되었습니다. //현재 레벨: Lv.20
위에 구현한 인스턴스 메서드에는 level
인스턴스 프로퍼티 값을 수정하는 코드가 있는데, 자신의 프로퍼티 값을 수정할 때 클래스 인스턴스 메서드는 신경 쓸 필요가 없지만, 구조체 혹은 열거형은 값 타입 이기 때문에 메서드 앞에 mutating
키워드를 반드시 사용해서 해당 메서드가 인스턴스 내부의 값을 변경한다는 것을 명시해줘야 한다.
![Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - 인스턴스 메서드 Instance Methods Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - 인스턴스 메서드 Instance Methods](https://blog.kakaocdn.net/dn/yGC9V/btrqFk7lfCN/mHEJde3t28jDvxOlGcHPs0/img.png)
struct LevelStruct { var level: Int = 0 { didSet { print("현재 레벨: Lv.\(level)") } } mutating func levelUp() { print("레벨업!") level += 1 } mutating func levelDown() { print("레벨 다운") level -= 1 if level < 0 { reset() } } mutating func jumpLevel(to: Int) { print("레벨이 \(to)로 점프 되었습니다.") level = to } mutating func reset() { print("레벨이 초기화 됩니다.") level = 0 print("레벨이 Lv.\(level)으로 초기화 되었습니다.") } } var levelStructInstance: LevelStruct = LevelStruct() levelStructInstance.levelUp() //레벨업! //현재 레벨: Lv.1
예시
struct Pokemon { var name: String func attack(with attackType: String) { print("\(name) uses \(attackType)!") } }
struct User { var name: String var street: String var city: String var postalCode: String func printAddress() -> String { return """ \(name) \(street) \(city) \(postalCode) """ } }
struct Car { var maxSpeed: Int func accelerate(to speed: Int) { if speed > maxSpeed { print("That's too fast!") } else { print("OK, let's go!") } } }
함수와 메서드의 차이
함수를 사용하면 기능의 이름을 지정하고 반복적으로 실행할 수 있으며 Swift의 메서드는 거의 동일한 작업을 수행한다.
그렇다면 차이점은?
유일한 차이점은 메서드는 struct
, enum
및 class
와 같은 유형에 속하지만 함수는 그렇지 않다는 것이다. 그게 유일한 차이점이다.
둘 다 가변 매개 변수를 포함하여 원하는 수의 매개 변수를 허용할 수 있으며 둘 다 값을 반환할 수 있다. 이 두 개는 너무 비슷해서 Swift에서는 여전히 func
키워드를 사용하여 메서드를 정의한다.
물론 구조체와 같은 특정 유형과 연관된다는 것은 메서드가 하나의 중요한 힘을 얻는다는 것을 의미한다. 즉, 해당 유형 내부의 다른 속성 및 메서드를 참조할 수 있다.
메서드 TEST: 문제를 풀려면 이곳을 클릭해주세요.
self 프로퍼티
타입의 모든 인스턴스는 암시적으로 생성된 self
프로퍼티를 갖는다. 이것은 인스턴스 자기 자신을 가리키는 프로퍼티이다. self
프로퍼티는 인스턴스를 더 명확히 지칭하고 싶을 때 사용하게 된다. self
프로퍼티를 사용하여 자체 인스턴스 메서드 내에서 현재 인스턴스를 참조할 수 있다.
func levelUp() { self.level += 1 }
Swift에서의 프로퍼티 사용 순서는 자동으로 메서드 내부에 선언된 지역변수 ➜ 메서드 매개변수 ➜ 인스턴스 프로퍼티 순으로 찾아 무엇을 지칭하는지 유추하게 된다.
class letterClass { var name: String = "" func sendLetter(to name: String) { print("\(name)에게 편지를 보냅니다.") self.name = name } } let Myletter: letterClass = letterClass() Myletter.sendLetter(to: "서근")
위 코드를 보면 인스턴스 프로퍼티인 name
과 매개변수로 넘어온 name
의 이름이 같은데 여기서 self.name = name
의 self
는 매개변수가 아닌 인스턴스 프로퍼티를 지칭한다. 쉽게 비교해보자면 아래와 같다.
![Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - self 프로퍼티 Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - self 프로퍼티](https://blog.kakaocdn.net/dn/cKocnZ/btrqHEcLfo9/z9zPqWZGHugpLNHIQZm6u0/img.png)
self 프로퍼티의 다른 용도로는 값 타입 인스턴스 자체의 값을 치환할 수 있다. 클래스 인스턴스는 참조 타입이라 self
프로퍼티에 다른 참조를 할당할 수 없고, 구조체와 열거형은 값 타입이라 self
프로퍼티를 사용하여 자신 자체를 치환할 수 있다.
class LevelClass { var level: Int = 0 func reset() { if level < 0 { self = LevelClass() //Cannot assign to value: 'self' is immutable } } }
↪︎ 클래스는 참조 타입이기 때문에 self
프로퍼티에 다른 참조를 할당할 수 없기에 error
struct LevelStruct { var level: Int = 0 mutating func levelUp() { print("레벨업!") level += 1 } mutating func reset() { print("초기화!") self = LevelStruct() } } var levelStructInstance: LevelStruct = LevelStruct() levelStructInstance.levelUp() //레벨업! print("현재 레벨 : Lv.\(levelStructInstance.level)") //현재 레벨 : Lv.1 levelStructInstance.reset() //초기화! print("현재 레벨 : Lv.\(levelStructInstance.level)") //현재 레벨 : Lv.0
↪︎ 구조체에서 reset
메서드의 self
프로퍼티는 LevelStruct
의 기본 값이 있는 인스턴스 프로퍼티 level = 0
으로 할당이 되었기 때문에 reset
메서드를 호출할 때 현재 레벨이 0이 된다.
enum OnOffSwitch { case on, off mutating func nextState() { self = self == .on ? .off : .on } } var toggle: OnOffSwitch = OnOffSwitch.off toggle.nextState() print("현재 스위치 상태 : \(toggle)") //현재 스위치 상태 : on
↪︎ 배열 내의 nextState
메서드를 보면 삼항 연산자를 사용했는데, self
(OnOffSwitch)는 self
(OnOffSwitch)가 .on
이라면 .Off
로 타입을 변경, 그게 아니라면 .on
으로 변경으로 할당해줬다.
![Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - self 프로퍼티 Swift : 기초문법 [메서드 #1 인스턴스 메서드, self 프로퍼티] - 메서드(Method) - self 프로퍼티](https://blog.kakaocdn.net/dn/cuf2Lv/btrqGsDUoX1/8q9Vyg0CuLHDj7n0Zlx8LK/img.png)
self 인스턴스
저장 인스턴스와 매개변수 이름이 같다면 반드시 self
를 붙혀 해당 타입의 저장 프로퍼티 인스터스 프로퍼티인지 구별해줘야 한다
읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
Swift : 기초문법 [메서드 #3 타입 메서드] (0) | 2022.01.14 |
---|---|
Swift : 기초문법 [메서드 #2 mutating] (0) | 2022.01.14 |
Swift : 기초문법 [프로퍼티#5 - 키 경로 KeyPath] (0) | 2022.01.10 |
Swift : 기초문법 [프로퍼티#4 - 타입 프로퍼티] (0) | 2022.01.10 |
Swift : 기초문법 [프로퍼티#3 - 프로퍼티 옵저버(감시자) - didSet, willSet] (0) | 2022.01.09 |