[Swift 프로그래밍] 메서드

이정훈·2022년 5월 21일
0

Swift 기본

목록 보기
8/22
post-thumbnail

본 내용은 스위프트 프로그래밍 3판 (야곰 지음) 교재를 공부한 내용을 바탕으로 작성 하였습니다.

스위프트에서 메서드는 클래스, 구조체, 열거형 등에 관련된 함수인 인스턴스 메서드와 타입 자체에 관련된 함수인 타입 메서드가 있다.

인스턴스 메서드


인스턴스 메서드는 위에서 간단히 설명한대로 인스턴스 내부에서 인스턴스에 관련된 값을 변경하거나 연산을 수행하는 기능을한다. 인스턴스 내부에서 구현하므로 인스턴스 생성시 메서드 호출이 가능하며, 형태는 일반적인 함수의 형태와 유사하다.

다음은 클래스에서 인스턴스 메서드를 사용하여 계산기 로직을 구현한 코드이다.

class CalculateClass {
    var result: Int = 0 {
        didSet {
            print("result: \(result)")
        }
    }
    //메서드
    func add(_ a: Int, _ b: Int) {
        result = a + b
    }
    func sub(_ a: Int, _ b: Int) {
        result = a - b
    }
    func mul(_ a: Int, _ b: Int) {
        result = a * b
    }
    func div(_ a: Int, _ b: Int) {
        if b == 0 {
            print("0으로 나눌 수 없습니다.")
        }
        else {
            result = a / b
        }
    }
}

var calculator1: CalculateClass = CalculateClass()
calculator1.add(5, 2)
calculator1.sub(5, 2)
calculator1.mul(5, 2)
calculator1.div(5, 2)

다음은 구조체에서 인스턴스 메서드를 사용하여 계산기를 구현하였다.
구조체에서의 인스턴스 메서드의 차이는 위의 코드에서는 각 인스턴스 메서드의 결과로 result 프로퍼티의 값이 바뀌었는데, 구조체와 같은 값 타입에서는 인스턴스 내부의 변화가 생기는 경우 인스턴스 메서드 앞에 mutating 키워드를 사용하여 내부 프로퍼티 값에 변화가 있다는 것을 명시 하여야 한다.

아래의 코드를 살펴보자

struct CalculateStruct {
    var result: Int = 0 {
        didSet {
            print("result: \(result)")
        }
    }
    //메서드
    mutating func add(_ a: Int, _ b: Int) {
        result = a + b
    }
    mutating func sub(_ a: Int, _ b: Int) {
        result = a - b
    }
    mutating func mul(_ a: Int, _ b: Int) {
        result = a * b
    }
    mutating func div(_ a: Int, _ b: Int) {
        if b == 0 {
            print("0으로 나눌 수 없습니다.")
        }
        else {
            result = a / b
        }
    }
}

var calculator2: CalculateStruct = CalculateStruct()
calculator2.add(5, 2)
calculator2.sub(5, 2)
calculator2.mul(5, 2)
calculator2.div(5, 2)

타입 메서드


스위프트의 타입 메서드는 다른 객체 지향 언어(예: Java)에서의 static 메서드(클래스 메서드)와 비슷하나 약간 다른 개념으로 사용된다.
스위프트에서의 타입 메서드는 타입 자체에서 호출이 가능한 메서드이다.
클래스 타입에서 타입 메서드static 키워드class 키워드를 사용하여 선언 할 수 있는데 클래스의 가장 큰 특징 중 하나인 상속에서 static 키워드로 정의한 타입 메서드는 재정의가 불가능하지만 class 키워드로 선언한 메서드는 재정의가 가능하다.

다음은 타입 메서드에 관한 간단한 예시이다.

class AClass {
    static func staticTypeMethod() {    //static 타입 메서드
        print("AClass staticTypeMethod")
    }
    
    class func classTypeMethod() {      //class 타입 메서드
        print("AClass classTypeMethod")
    }
}

class BClass: AClass {  //상속
    //class 타입 메서드 재정의
    override class func classTypeMethod() {
        print("BClass classTypeMethod")
    }
}

AClass.staticTypeMethod()
AClass.classTypeMethod()
BClass.classTypeMethod()

BClass 클래스는 AClass를 상속 받아 class 키워드로 선언한 타입 메서드를 재정의 한 것을 볼 수 있다.

self 프로퍼티


스위프트의 self 프로퍼티는 자바의 this와 유사한 개념이다.
인스턴스 메서드에서 self를 사용할 경우 이때 self는 인스턴스 자체를 의미한다.
하지만 타입 메서드에서 self를 사용할 경우 self는 타입 자체를 의미한다.

다음에서 타입 메서드에서 self 프로퍼티를 사용한 예시를 살펴 보자

struct PhotoSize {
    static var size: Int = 100
    
    static func zoomIn() {
        self.size =  200    //self -> PhotoSize
    }
}

class Photo {
    var originalSize: Int = 100
    
    func enlarge() {
        PhotoSize.zoomIn()
    }
    
    func reset() {
        PhotoSize.size = self.originalSize    //self -> 인스턴스
    }
}

let myPhoto: Photo = Photo()
myPhoto.enlarge()
print(PhotoSize.size)
myPhoto.reset()
print(PhotoSize.size)

위의 Photo클래스의 reset 메서드에서 사용한 self는 인스턴스 메서드 내부에서 사용한 selfPhoto클래스로 생성된 인스턴스 자체를 가리키고, PhotoSize 구조체의 zoomIn 메서드에서 사용한 self는 타입 메서드에서 사용한 self로 타입 메서드가 속한 PhotoSize 구조체 타입 자체을 가리킨다.

  • 타입 메서드 내부에서 self가 사용되었을때, 이때 self 는 타입 그 자체를 나타낸다.

인스턴스를 함수처럼 호출하는 메서드

스위프트에는 메서드 이름을 callAsFunction이라고 선언하면 인스턴스를 함수처럼 호출 할 수 있다.

struct Person {
    var name: String = "이철수"
    
    func callAsFunction() {
        print("저의 이름은 \(name)입니다. 반갑습니다!")
    }
    
    func callAsFunction(age: Int) {
        print("저의 나이는 \(age)입니다.")
    }
    
    func callAsFunction(height: Int) {
        print("저의 키는 \(height)입니다.")
    }
    
    mutating func callAsFunction(name: String) {
        self.name = name
    }
}

var introduce: Person = Person()
introduce.callAsFunction()
introduce()         //위의 표현과 동일한 표현
introduce.callAsFunction(age: 99)
introduce(age: 99)  //위의 표현과 동일한 표현
introduce.callAsFunction(height: 180)
introduce(height: 180)

위의 코드와 같이 메서드 이름을 callAsFunction으로 선언하면 introduce.callAsFunction()introduce()는 완전히 동일한 기능을 한다.

profile
새롭게 알게된 것을 기록하는 공간

0개의 댓글