[Swift] Weekly Conference

simoniful·2021년 10월 21일
0

Swift

목록 보기
7/9
post-thumbnail

Class

클래스는 필요한 기능을 조합하여 하나로 묶고 이름을 붙여서 언제든지 편하게 불러와 사용할 수 있게 만든 기능입니다. 따라서, 프로그램의 여러가지 기능을 클래스로 구분하여 부분적으로 재활용이 가능합니다. 객체지향 프로그래밍에서는 클래스 기반의 코딩을 지향하며 내부의 멤버프로퍼티메서드를 적극적으로 활용합니다. iOS의 UIKit Framework는 대부분 클래스로 구성되어 있습니다.

Instance(인스턴스)

정의되어 있는 클래스를 활용하여 생성한 객체를 인스턴스라고 합니다. 만들어진 인스턴스를 통하여 프로퍼티와 메서드에 접근하여 활용할 수 있습니다.

class Monster {
    // 프로퍼티 선언
    var clothe: String = "파란옷" // Default Initializer
    var speed: Int
    var power: Int
    var expriencePoint: Double
    
    // 초기화 구문
    init(clothe: String, speed: Int, power: Int, expriencePoint: Double) {
        self.clothe = clothe
        self.speed = speed
        self.power = power
        self.expriencePoint = expriencePoint
    }

    func attack() {
        print("몬스터 공격!")
    }
}

var easyMoster = Monster(clothe: "Orange", speed: 1, power: 10, expriencePoint: 50.0)
var hardMonster = Monster(clothe: "Blue", speed: 10, power: 500, expriencePoint: 10000.0)

Inheritance(상속)

클래스는 다른 클래스로 부터 프로퍼티나 메서드를 상속 받아 사용할 수 있습니다. 이 때 상속을 받은 클래스는 SubClass(자식클래스)라고 부르고 프로퍼티와 메서드를 상속을 해준 클래스는 SuperClass(부모클래스)라고 부릅니다. 이를 상속하는 경우 super() 메서드를 필수적으로 실행하여

Member Override

부모클래스로부터 물려받은 멤버(프로퍼티, 메서드)를 자식 클래스에서 사용할 때, 변경하여 사용할 수 있습니다. 이를 재정의라고 합니다.
자식클래스에서 해당 클래스만의 기능으로 멤버를 재정의했지만, 부모클래서의 멤버도 사용하고 싶은 경우 super 프로퍼티를 사용하여 호출하는 것이 가능합니다.

class BossMonster: Monster {
    var bossName = "청의태자"
    
    func bossUniqueAttack() {
        print("청룡마룡참!")
    }
    override func attack() {
        super.attack()
        print("보스 공격!")
    }
}

var boss = BossMonster(clothe: "Black", speed: 100, power: 500000, expriencePoint: 2000000)

Struct

구조체도 클래스와 마찬가지로 데이터를 구조화하여 관리하는데 사용이 됩니다. swift에서 Int, String 등 기본형 데이터 타입과 Array, Dictionary, Set 등 콜렉션형 데이터 타입, 그리고 프로그래머 마음대로 만드는 tuple, enum 열거형은 모두 struct로 구현이 되어있습니다. 마치 Javascript에서 표준 내장 객체 개념과 유사합니다.

@frozen struct Int

Initializer

클래스와 구조체가 인스턴스를 생성하기 위해서는 선언되어 있는 모든 프로퍼티가 초기화가 잘 되어 있어야 합니다. 초기화가 되어 있는 않은 경우 컴파일 에러가 발생하게 됩니다.

프로퍼티가 옵셔널 타입으로 선언이 되어 있다면 nil도 포함하기에 컴파일 에러는 발생하지 않습니다. 하지만, 인스턴스 생성 시 nil일 경우 런타임 환경에서 에러가 발생할 수 있기에 주의를 하여 사용해야 합니다. 따라서 단순히 에러를 무마하기 위한 수단으로 옵셔널 타입선언은 지양해야 합니다.

직접 Default Initializer로 프로퍼티에 값을 할당하여 사용하는 경우도 있습니다. 그렇지만, 초기화를 돕는 메서드를 Init()을 클래스 내에 활용하여, 해당 인스턴스에 인자값(parameter)를 전달하는 형태로 대부분의 프로퍼티를 초기화 합니다. Class의 경우 해당 메서드를 통하여 초기화하는 것이 일반적이며, Struct의 경우 멤버와이즈 초기화 구문(Memberwise initializer)으로 모든 프로퍼티 값을 초기화하는 구문을 자동으로 제공합니다.


Value Type / Reference Type

var nickname: String = "고래밥"
var subNickname = nickname
nickname = "칙촉"
print(nickname) // 칙촉
print(subNickname) // 고래밥
// // 서로가 완벽하게 구분된 공간 복사한 '값'이 들어가게 됨

JS를 할 때도 나왔던 개념입니다. call by reference / call by value 라는 개념으로 처음 접했고 이해하는데 상당한 시간이 걸렸습니다. 함수 안에서 전달하는 인자가 값이냐 참조형이냐에 따라서 메모리의 주소 사용이 달라지게 되는 개념이었습니다. swift를 하면서는 Construct와 Class에서 확연한 차이점을 알 수 있었습니다.

🔗 JS에서 값(value) vs 참조(reference)

Struct는 값 타입에 기반합니다. 인스턴스를 생성하여 다른 변수에 할당한 경우. 기존의 인스턴스와 독립적으로 동작합니다. 인스턴스 값 자체를 복사한 새로운 인스턴스가 존재하게 되는 개념으로, 기존 인스턴스의 프로퍼티를 변경하더라도 서로 영향을 미치지 않습니다.

Class는 참조 타입에 기반합니다. 인스턴스를 생성하여 다른 변수에 할당할 경우, 메모리의 주소 정보를 그대로 전달합니다. 전달된 주소 정보를 따라 값을 찾아 나서기에 인스턴스들은 공통적인 값에 도달하여 이를 공유하여 사용하게 됩니다.

class SuperBoss {
    var name: String
    var level: Int
    var power: Int
    
    init(name: String, level: Int, power: Int) {
        self.name = name
        self.level = level
        self.power = power
    }
}

var hardStepBoss = SuperBoss(name: "쉬운 보스", level: 1, power: 10)
var easyStepBoss = hardStepBoss

hardStepBoss.power = 50000
hardStepBoss.level = 100
hardStepBoss.name = "어려운 보스"

print(hardStepBoss.name, hardStepBoss.level, hardStepBoss.power) // 어려운 보스 100 50000
print(easyStepBoss.name, easyStepBoss.level, easyStepBoss.power) // 어려운 보스 100 50000

🔗 Initialization

profile
소신있게 정진합니다.

0개의 댓글