
TIL 5일 차 - 클래스와 구조체 학습하기
1. 클래스와 구조체는 대체 뭐가 다른가?
2. 클래스와 구조체를 활용해 데이터를 구조화하고 효율적으로 관리하기
3. 값 타입(Struct)와 참조 타입(Class)의 차이를 이해하고 적절한 상황에 사용하기
클래스(Class)
쉽게 설명하자면 (속성property + 행동 method)을 합쳐놓은 개념.. 붕어빵 틀이다.
이걸 이용해서 붕어빵을 찍어낼수있고 캡슐화로 재사용과 유지보수에도 용이하다.
이 클래스를 배우면 이제 본격적으로 객체지향프로그래밍을 시작한다고 생각하면 된다.
// 클래스의 기본 문법
class 클래스이름 {
var 속성이름: 타입
init(초기화 할 속성 이름: 이 속성의 타입) {
self.속성이름 = 속성이름
}
func 메서드이름() {
실행할 코드
}
}
// 클래스 내의 변수, 상수는 프로퍼티라고 함
// 클래스 내의 함수는 메소드라고 함
//이름,나이 변수와 프린트 메서드 클래스
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
func introduce() {
print("안녕하세요, 저는 \(name)이고 \(age)살이에요.")
}
}
let person1 = Person(name: "명수", age: 25)
person1.introduce() // '안녕하세요, 저는 명수이고 25살이에요.'
let person2 = Person(name: "도자캣", age: 29)
// person1과 person2는 서로같은 Person 클래스의 인스턴스이지만 각각 다른 인스턴스이다.
1) 클래스는 구조체와 달리 참조 타입이다.
// 클래스는 참조 타입이다!!!!!!!!!!
let a = Person(name: "명수", age: 56)
let b = a
b.name = "재석"
print(a.name) // 재석 출력 됨
// a의 주소값이 b에게 대입되었으므로 a와 b는 같은 인스턴스를 가리키게 됨
2) 상속이 가능하다.
// Student 클래스가 Person을 상속받음
// 부모가 가진 속성과 기능을 재사용 가능하다.
class Student: Person {
var school: String
init(name: String, age: Int, school: String) {
self.school = school
super.init(name: name, age: age)
// super는 내가 물려받은 부모클래스를 뜻함
// 부모클래스가 가진 속성도 빼먹지않고 초기화 해주어야 한다.
}
}
3) iOS UI는 거의 다 클래스다.
// 화면에 올라가는 UI 객체들
// 생명주기와 상태 공유가 필요하므로 참조타입인 클래스를 사용한다.
let label = UILabel()
let button = UIButton()
let viewController = UIViewController()
클래스의 초기화
- class안에서 사용되는 변수와 상수인 프로퍼티에는 default값을 정해줄 수 있음
- class의 인스턴스를 생성할때는 반드시 초기화를 해줘야 함
- 모든 프로퍼티에 default값을 제공한다면 init 초기화를 생략할 수 있음
- 모든 프로퍼티가 Optional인 경우 init 초기화를 생략할 수 있음
- 초기화를 도와주는 컨비니언스 이니셜라이저(convenience init)를 제공함. 구조체에서는 제공 X
초기화의 방법들
1. 지정 초기화
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
let person = Person(name: "JH", age: 24)
2. 기본값 초기화
- 프로퍼티에 기본값을 넣으면 초기화 안 해도 됨
- 하지만 프로퍼티의 기본값이 하나라도 빠진다면 init을 구현해 모든 값을 프로퍼티의 값을 채워야 함
class Person {
var name: String = "이름없음"
var age: Int = 0
}
3. 여러 개의 init 사용
- 여러 가지의 init을 만들면 여러가지 방법으로 class를 초기화할 수 있음
// 지정 초기화
// 일반적인 init
class Person {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
init(name: String) {
self.name = name
self.age = 0
}
init() {
self.name = "이름없음"
self.age = 24
}
}
4. convenience init: 보조 초기화
- 클래스에서만 사용할 수 있는 기능으로 구조체에서는 사용 불가
// 파라미터에 값을 할당하지않고 컨비니언스 이니셜라이즈를 사용할 수 있음
class Person {
var name: String
var age: Int
init(name: String, aage: Int) {
self.name = name
self.age = age
}
convenience init(name: String) {
self.init(name: name, age:0)
}
}
let person = Person(name: "이름만 입력")
print(person.age) // 0 출력
+ deinit: 소멸자
- class에서만 사용 가능함
- 사용이 종료된 인스턴스가 메모리에서 해제될 때 자동 호출됨
- 직접 호출은 불가
deinit {
// 구현부
}
구조체(Struct)
대체 얘는 뭐고 왜 필요하냐!
=> 간단한 데이터 집합을 표현하고 싶을 때 구조체를 사용한다.
=> 값을 복사해서 사용, 즉 독립적인 복사본이 필요한 경우에는 구조체가 적합하다.
그냥 즉 프린트기라고 생각하면 된다. 아까 클래스는 집주소를 가져왔다면 구조체는 그 집의 알맹이만 복사해 온 느낌..!
아무리 복사해 와도 그 집의 주인은 그대로임
// 구조체 예제
struct Rectangle {
var width: Double
var height: Double
func area() -> Double {
return width*height
}
}
let rect1 = Rectangle(width:5.0, height:10.0)
print(rect1.area())
// 50.0 출력
var rect2 = rect1
rect2.width = 20.0
print(rect1.area())
// 50.0 출력
print(rect2.area())
// 200.0 출력
출력 방식이 참조방식인 클래스와는 다르게 값 타입(Value Type)으로 되는 것을 확인할 수 있다.
- 멤버와이즈 이니셜라이저를 제공해 직접 init을 정의하지 않아도 모든 프로퍼티의 초기화를 자동으로 생성해 주는 기능이 있음
- 메서드에서 프로퍼티를 변경하려면 mutating 키워드를 사용해야 함
- struct은 값타입이므로 당연히 상속은 불가능함
- 인스턴스를 let으로 만들면 내부 프로퍼티를 변경할 수 없으므로 프로퍼티를 변경하려면 var로 만들어야 함
memberwise init 사용해 초기화하는 법
struct Person {
var name: String
var age: Int
// class와 다르게 init을 생성하지않아도 자동으로 됨
}
var person = Person(name: "JH", age: 24)
지정 초기화
// init을 직접 생성하면 memberwise init이 사용되지 않음
struct Person {
var name: String = "이름없음"
var age: Int = 1
init() {
print("init")
}
}
Person()
Person(name: "JH") // Error: 멤버와이즈 init 적용 안되었음
Person(age: 24) // Error: 파라미터로 ge만 전달하는 init을 지정 안했으므로 에러
Person(name: "JH", age: 24) // Error: argument passed to call that takes no arguments
함수에 mutating 붙이기 (함수를 사용해 프로퍼티의 값이 변경될 때)
struct Person {
var name: String
var age: Int
func introduce() {
print("안녕하세요 \(name)입니다. 저는 \(age)살 입니다.")
}
mutating func happyNewYear() {
age += 1
}
}
var me = Person(name: "JH", age: 24)
me.age // 24
me.name // 'JH'
me.introduce() // '안녕하세요 JH입니다. 저는 24살 입니다.'
me.happyNewYear()
me.introduce() // '안녕하세요 JH입니다. 저는 25살 입니다.'
'iOS > Swift ' 카테고리의 다른 글
| [iOS-Swift] 조건문 (0) | 2026.01.06 |
|---|---|
| [iOS-Swift] 기본 데이터 타입 (0) | 2026.01.06 |
| [iOS-Swift] 변수와 상수 (0) | 2026.01.06 |
| [iOS] 앱 아키텍쳐 기초 (MVC,MVVM) (0) | 2026.01.05 |
| [iOS-Swift] 함수와 클로저, 옵셔널 (1) | 2025.12.31 |