참조 타입과 값 타입의 차이점, Swift에서 클래스 사용법
클래스란 무엇일까?
클래스는 참조 타입(reference type) 이다.
참조 타입이란, 어떤 값을 대입하거나 전달할 때, 값 자체를 복사(copy) 하는 게 아니라 그 값이 저장된 '주소(reference)'를 공유한다는 뜻이다.
Swift에서 클래스를 정의할 때는 class 키워드를 사용하고, 클래스 이름은 대문자 카멜케이스(예: Person, Student)를 따른다.
class Sample {
var mutableProperty: Int = 100
let immutableProperty: Int = 100
static var typeProperty: Int = 100
func instanceMethod() {
print("instance method")
}
static func typeMethod() {
print("type method - static")
}
class func classMethod() {
print("type method - class")
}
}
이처럼 클래스 안에는 변수(var), 상수(let), 메서드(func) 등을 넣어 여러 가지 기능을 정의할 수 있다.
let으로 선언했는데 프로퍼티는 수정할 수 있다?
조금 헷갈릴 수 있는 부분이다.
클래스를 인스턴스화 할 때 let으로 선언하면, 참조 자체를 바꿀 수 없을 뿐, 그 안의 프로퍼티(속성) 는 얼마든지 수정할 수 있다.
예를 들어보자.
let sample = Sample()
sample.mutableProperty = 200 // OK
// sample = Sample() // 오류! 참조를 바꿀 수 없음
>> sample이라는 참조 자체는 고정되지만, sample이 가리키고 있는 객체 안의 속성 값은 변경 가능하다.
쉽게 말하면,
"책은 같은 책을 계속 들고 있어야 하지만, 책 안에 낙서는 해도 된다" 라고 이해하면 된다.
클래스와 구조체(struct)의 차이점
클래스를 공부하다 보면 자연스럽게 드는 질문이 있다.
"그럼 구조체(struct) 랑 뭐가 다른데?"
정리하면 이렇게 된다:
구분 | 클래스(Class) | 구조체(Struct) |
타입 | 참조 타입 (Reference) | 값 타입 (Value) |
상속 | 가능 | 불가 |
메모리 관리 | ARC 적용 | 복사(Copy) |
let 선언 시 | 프로퍼티 수정 가능 | 전체 불변 |
핵심 차이점은
클래스는 참조 타입, 구조체는 값 타입이라는 점이다.
구조체는 =로 대입할 때 값을 통째로 복사한다.
클래스는 같은 객체를 참조한다.
코드로 비교해보자:)
class Dog {
var name: String
init(name: String) { self.name = name }
}
var dogA = Dog(name: "초코")
var dogB = dogA // 복사 X, 같은 걸 가리킴
dogB.name = "콩이"
print(dogA.name) // 콩이
print(dogB.name) // 콩이
반면 구조체는?
struct Cat {
var name: String
}
var catA = Cat(name: "나비")
var catB = catA // 복사 O, 따로 존재
catB.name = "야옹이"
print(catA.name) // 나비
print(catB.name) // 야옹이
정리하면,
클래스는 복사 안 한다. 같은 걸 같이 본다.
구조체는 복사해서 따로 가지고 논다.
상속은 어떻게 할까?
Swift의 클래스는 상속을 지원한다.
상속이란, 기존 클래스(부모 클래스)의 기능을 새로운 클래스(자식 클래스)가 물려받는 것이다.
단, Swift에서는 다중 상속(여러 부모 클래스 상속) 은 허용되지 않는다. 하나의 부모 클래스만 상속 가능하다.
상속 예시
class Person {
var name: String = "Unknown"
func introduce() {
print("안녕하세요. 저는 \(name)입니다.")
}
}
class Student: Person { // Person을 상속받음
var school: String = "Unknown School"
func study() {
print("\(name)이(가) \(school)에서 공부합니다.")
}
}
let student = Student()
student.name = "지민"
student.school = "Swift University"
student.introduce() // 안녕하세요. 저는 지민입니다.
student.study() // 지민이(가) Swift University에서 공부합니다.
여기서 Student: Person 부분에 :가 들어간 이유는,
Student가 Person을 상속받아 확장한다는 뜻을 명확하게 나타내기 위해서다.
:는 그냥 "포함한다", "물려받는다" 라고 이해하면 된다.
그럼, = 대입 연산자는 어떻게 생각해야 할까?
Swift에서 클래스 인스턴스를 =로 대입할 때, 초보자가 실수하기 쉬운 부분이 있다.
"값을 복사하는 거 아닐까?"라고 생각할 수 있는데, 아니다.
클래스에서는 =은 대입(assign) 이 아니라, 같은 걸 가리키게 한다(reference sharing) 고 이해하는 게 맞다.
즉, dogA = dogB를 하면,
dogA와 dogB가 같은 개체를 가리킨다. 둘 중 하나를 수정하면, 다른 하나도 영향을 받는다.
+정리
- 클래스는 참조 타입이다.
- let으로 선언해도 내부 프로퍼티 수정 가능.
- 클래스는 =을 써도 복사 안 하고 같은 걸 가리킨다.
- 구조체는 값 타입이라 복사된다.
- 클래스는 상속이 가능하다 (다중 상속은 불가).
'IT' 카테고리의 다른 글
클래스 vs 구조체/열거형, 무엇이 다를까? Swift 값 타입과 참조 타입 정리 (0) | 2025.05.02 |
---|---|
Swift enum 제대로 이해하기: rawValue부터 메서드까지 (0) | 2025.04.30 |
스위프트 구조체와 객체지향 프로그래밍 기초 (0) | 2025.04.28 |
앱 크래시 방지! Swift 옵셔널 바인딩과 강제 추출 차이점 (0) | 2025.04.26 |
Swift 옵셔널 정리 : ?와 ! 차이 + 안전한 사용법 (0) | 2025.04.25 |
댓글
이 글 공유하기
다른 글
-
클래스 vs 구조체/열거형, 무엇이 다를까? Swift 값 타입과 참조 타입 정리
클래스 vs 구조체/열거형, 무엇이 다를까? Swift 값 타입과 참조 타입 정리
2025.05.02 -
Swift enum 제대로 이해하기: rawValue부터 메서드까지
Swift enum 제대로 이해하기: rawValue부터 메서드까지
2025.04.30 -
스위프트 구조체와 객체지향 프로그래밍 기초
스위프트 구조체와 객체지향 프로그래밍 기초
2025.04.28 -
앱 크래시 방지! Swift 옵셔널 바인딩과 강제 추출 차이점
앱 크래시 방지! Swift 옵셔널 바인딩과 강제 추출 차이점
2025.04.26