Swift/개념 & 응용

[Swift] Swift 문법 - 클래스(Class) (1)

유정주 2021. 8. 25. 00:10
반응형

안녕하세요.

 

오늘은 Swift의 클래스에 대해 알아보겠습니다.

클래스도 함수와 동일하게 총 2회로 나누어 포스팅 할 예정입니다.

 

Swift도 객체 지향 언어로서 클래스에 대한 중요도가 상당히 높습니다.

처음 공부하며 작성한 포스팅으로 추후 내용을 추가할 수도 있습니다.

 

그럼 시작하겠습니다.


참고 자료

Apple Swift Document

https://developer.apple.com/documentation/swift

 

해당 포스팅은 Smile Han님의 유튜브 영상을 참고하며 작성하였습니다.

https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA


클래스(Class)

객체 지향에서 클래스는 아주 큰 의미를 가집니다.

여러 속성 등을 캡슐화를 하여 객체화하고 이를 이용해 프로그래밍한다는 것이 객체 지향의 큰 특징 중 하나이기 때문입니다.

 

Instance

클래스는 하나의 설계도입니다.

이 설계도를 이용해 객체를 만들면 실제 메모리에 할당되는데 이 객체를 Instance라고 합니다.

쉽게 사용할 수 있고 재사용할 수 있는 모듈이죠.

instance는 데이터 변수인 property와 동작에 관한 메서드(method)로 구성됩니다.

 

클래스 정의 방법

클래스를 정의하는 방법입니다.

class 클래스 이름: 부모 클래스 {
	//property
	//instance method
	//type method
}

부모클래스는 상속이 필요할 때만 작성됩니다.

 

property에는 클래스 내에 포함되는 변수와 상수를 정의합니다.

instance method는 객체가 호출하는 메서드를 정의합니다.

type method 클래스가 호출하는 메서드를 정의합니다. class method라고도 하네요.

 

하나하나 살펴보겠습니다.


Property

property란 클래스의 속성을 나타냅니다.

예시로 사용할 사람으로 치면 나이, 성별, 이름 등이 property입니다.

 

property는 stored property와 computed property로 나뉩니다.

기본적으로 Swift에서 property라 지칭되는 것은 stored property를 의미합니다.

 

Swift의 property는 아래 세 가지 조건이 있습니다.

    1. 초기값이 존재해야 한다.

    2. 생성자(initializer)를 이용해 초기화가 이뤄져야 한다.

    3. 초기화를 하지 않고 싶다면 Optional로 선언해야 한다.

 

C에서는 초기화를 하지 않으면 쓰레기 값이 들어가고 Java 등에서는 초기화를 안 해도 0으로 초기화가 되지만

Swift에서는 property는 반드시 초기화를 해야합니다.

만약 초기화를 하지 않는다면 어떻게 될까요?

class Person {
    var gender : String
    var age : Int
    var weight : Double
}
note: stored property 'gender' without initial value prevents synthesized initializers

초기화를 하지 않은 클래스를 빌드해보면 초기화를 제안하는 note가 뜨네요.

이 클래스를 아직 사용하지 않았기에 note로 끝나는 것이지

초기화를 하지 않고 instance를 선언하면 접근 불가하다는 아래의 에러를 냅니다.

'Person' cannot be constructed because it has no accessible initializers

 

따라서 아래처럼 각 property마다 초기화를 해주도록 합시다.

class Person {
    var gender : String?
    var age : Int = 0
    var weight : Double = 0
}

옵셔널 변수는 자동으로 nil이 됩니다. 참고해주세요.


Method

method는 클래스의 행위입니다.

사람을 예시로 든다면 말하는 행위, 걷는 행위가 method가 될 수 있습니다.

 

method는 instance method와 type method로 나뉩니다.

instance method는 instance가 호출하여 동작하는 method이고

type method는 class가 사용하는 method입니다.

 

instance method 정의

instance method는 class 내부에서 func 키워드를 이용해 정의할 수 있습니다.

class Person {
    var name : String = "Unknown"
    var age : Int = 0
    var weight : Double = 0

    func display() { //instance method
        print("\(name) is \(age) and weighs \(weight)kg")
    }
}

var jeong: Person = Person()
jeong.display()
//실행결과
//Unknown is 0 and weighs 0.0kg

Person 클래스를 만들고 jeong 이름의 instance를 생성했습니다.

이 jeong에게 아무런 정보를 주지 않고 display()를 하라고 명령했기 때문에

초기값을 출력합니다.

 

type method 정의

instance method와 비슷하나 func 앞에 static이나 class 키워드를 앞에 붙여서 정의합니다.

class 키워드로 만든 타입 메서드는 자식 클래스에서 override가 가능합니다.

 

type method는 클래스가 사용하는 method로

이는 글로 이해하기는 힘들 수 있어 예제를 준비했습니다.

class Person {
    var name : String?
    var age : Int = 0
    var weight : Double = 0

    func display() { //instance method
        print("\(name) is \(age) and weighs \(weight)kg")
    }

    class func cPerson() {
        print("cPerson() is type method");
    }

    static func scPerson() {
        print("scPerson() is type method");
    }
}

Person.cPerson()
Person.scPerson()
//실행결과
//cPerson() is type method
//scPerson() is type method

class를 이용한 type method 하나와 static을 이용한 type method 하나를 정의하였습니다.

클래스가 사용하는 method라는 것은 예제를 보면서 바로 이해했을 것입니다.

 

instance method는 클래스를 이용해 instance를 만들고 instance가 method를 호출하였습니다.

type method는 instance가 필요없이 클래스가 바로 호출한다는 것입니다.

 

만약 instance가 type method를 부른다면 어떻게 될까요?

var jeong = Person()
jeong.cPerson()
//실행결과
//error: static member 'cPerson' cannot be used on instance of type 'Person'

위와 같은 에러가 나오네요.

이렇게 instance는 type method를 호출하지 못한다는 것을 알 수 있었습니다.


Instance

instance를 생성하는 방법에 대해 알아보겠습니다.

var 인스턴스명 : 클래스명 = 클래스명()
var 인스턴스명 = 클래스명()

기본적인 변수, 상수 선언과 형태는 동일합니다.

다만 자료형이 Swift의 기본 자료형이 아니라 직접 만든 Class라는 차이점이 있죠.

var jeong : Person = Person()
var jeong = Person()

생성자(initializer)를 말할 때 나올 내용이지만

클래스명()는 내부 코드의 default initializer를 나타냅니다.

 

메서드와 프로퍼티 접근

instance는 .키워드를 써서 property와 method에 접근 가능합니다.

인스턴스명.property
인스턴스명.method()
print(jeong.name, jeong.age, jeong.weight)
jeong.display()
//실행결과
//nil 0 0.0
//nil is 0 and weighs 0.0kg

name은 옵셔널 변수이고 따로 할당을 해주지 않았기 때문에 nil이 출력되었습니다.

기타 property도 모두 초기값이 출력되었습니다.


initialization

생성자는 인스턴스가 생성되는 시점에 property를 초기화할 수 있습니다.

인스턴스가 생설될 때 자동으로 생성됩니다.

위에서 initializer를 따로 호출하지 않아도 초기화값으로 instance가 생성된 것처럼요.

단, 하나라도 직접 만들면 default initializer는 사라집니다.

 

designated initializer

모든 property를 초기화하는 생성자를 의미합니다.

designated initializer를 만들면 property의 초기값을 직접 설정하지 않아도 됩니다.

class Person {
    var name : String
    var age : Int
    var weight : Double

    func display() { //instance method
        print("\(name) is \(age) and weighs \(weight)kg")
    }

    init(yourName: String, yourAge: Int, yourWeight: Double) {
        name = yourName
        age = yourAge
        weight = yourWeight
    } //designated initializer
}

var jeong = Person(yourName: "Jeongju", yourAge: 23, yourWeight: 63.5)
jeong.display()
//실행결과
//Jeongju is 23 and weighs 63.5kg

모든 property를 초기화하는 designated initializer를 정의했습니다.

처음 예제와는 다르게 instance를 생성할 때 인수를 전달합니다.

이렇게 전달한 값으로 property가 초기화가 되고 결과가 출력이 됩니다.

 

각 매개변수로 yourName, yourAge, yourWeight로 설정했는데요.

코딩에 조금 지식이 있으신 분들은 어색하게 느껴지실겁니다.

그 이유는 아래 self에서 다루겠습니다.

 

소멸자

인스턴스가 소멸될 때 자동으로 호출됩니다.

사용법은 init() { }과 기본적으로 비슷하나 deinit { }으로 사용합니다.

초기에는 사용할 일이 없다고 하네요..ㅎ 

 

self

initializer에서 self를 사용하지 않을 땐 property와 매개변수 이름이 같으면 안 됩니다.

그래서 위의 예시에서 name, age, weight를 매개변수명으로 사용하지 않았습니다.

 

하지만 변수 이름 짓기도 힘든데 매번 다시 생각하는 것도 골치입니다.

따라서 property명과 매개변수명을 같이 쓸 수 있도록 해주는게 self 키워드입니다.

self는 클래스 안의 메소드나 property를 가리키기 때문에 컴파일러가 혼돈하지 않습니다.

 

(java의 this처럼)self와 비슷한 문법을 가진 언어라면

90% 이상의 프로그래머가 self를 사용하여 생성자를 정의합니다. 

혹시 코딩이 처음이시라면 미리부터 self를 이용하는 코딩 스타일을 익히시는 걸 추천합니다.

class Person {
    var name : String
    var age : Int
    var weight : Double

    func display() { //instance method
        print("\(name) is \(age) and weighs \(weight)kg")
    }

    init(name: String, age: Int, weight: Double) {
        self.name = name
        self.age = age
        self.weight = weight
    } //designated initializer
}

var jeong = Person(name: "Jeongju", age: 23, weight: 63.5)
jeong.display()
//실행결과
//Jeongju is 23 and weighs 63.5kg

self를 사용하지 않는 예제와 비교했을 때 결과는 동일한데 무척이나 보기 좋아졌습니다.

코드는 가독성, 직관성도 중요하니까요.

하지만 Swift는 self를 꼭 필요할 때가 아니라면 자제하기를 권장한답니다.

실제 앱을 개발할 때 신경을 써야하는 부분입니다.


Swift 문법 - 클래스(Class) (1)이 끝이 났습니다.

아래 링크를 누르면 다음 포스팅을 바로 볼 수 있습니다.

2021.08.26 - [개발,IT,코딩/iOS, Swift] - [Swift] Swift 문법 - 클래스(Class) (2)

 

class, property, method, instance의 기본 개념에 대해 알아보았는데요.

초반과 비교했을 때 확실히 볼륨이 커진 것 같네요.

 

감사합니다.


아직은 초보 개발자입니다.

더 효율적인 코드 훈수 환영합니다!

공감 댓글 부탁드립니다.

 

 

반응형