메서드(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
키워드를 반드시 사용해서 해당 메서드가 인스턴스 내부의 값을 변경한다는 것을 명시해줘야 한다.
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
는 매개변수가 아닌 인스턴스 프로퍼티를 지칭한다. 쉽게 비교해보자면 아래와 같다.
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
으로 변경으로 할당해줬다.
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 |