1️⃣ 개념 바로 알기
1. Struct와 Class
1. Struct(구조체):
- 값 타입(Value Type)으로, 메모리에서 값을 복사해 사용하므로 독립된 인스턴스 생성
- 상속 불가능
- 주로 데이터를 저장하거나 간단한 로직을 수행할 때 사용
2. Class(클래스):
- 참조 타입(Reference Type)으로, 메모리에서 동일한 인스턴스를 여러 곳에서 참조
- 상속 가능
- 객체지향 프로그래밍의 주요 개념으로 사용
🛠️ 주요 차이점
특징 | Struct | Class |
메모리 구조 | Stack | Heap |
타입 | 값 타입 (Value Type) | 참조 타입 (Reference Type) |
상속 | 불가능 | 가능 |
성능 | 메모리 복사가 빨라 성능 우수 | 메모리 참조로 성능 낮음 |
2. 프로토콜
- 프로토콜(Protocol)은 특정 기능을 정의한 청사진입니다
- Struct, Class, Enum에서 프로토콜을 채택(Adopt)하고 구현(Implement)할 수 있습니다
- 용도
- 코드를 재사용 가능하고 유연하게 설계
- 프로토콜 기반의 설계 방식 (Protocol-Oriented Programming)을 가능하게 합니다
🛠️ 프로토콜 문법 예제
protocol Greetable {
func greet() -> String
}
struct Person: Greetable {
var name: String
func greet() -> String {
return "Hello, \(name)!"
}
}
let person = Person(name: "Alice")
print(person.greet()) // "Hello, Alice"
[ 실행 결과 ]
2️⃣ 직접 구현해보기
1. Struct 구현하기
- 이름과 나이를 저장하는 User Struct를 작성하고, 두 명의 독립적인 사용자 인스턴스를 생성해주세요
- 두 인스턴스의 값을 변경한 후, 각 인스턴스가 서로 독립적임을 확인하세요
[ 실습 코드 ]
import Foundation
struct User {
var name: String
var age: Int
}
var user1 = User(name: "Mario", age: 30)
var user2 = User(name: "Seongpil", age: 26)
print("User1 : \(user1.name),\(user1.age)")
print("User2 : \(user2.name),\(user2.age)")
// 값 변경
user1.name = "Luigi"
user1.age = 29
user2.name = "Dave"
user2.age = 22
print("------------------------------------")
print("User1 : \(user1.name),\(user1.age)")
print("User2 : \(user2.name),\(user2.age)")
[ 실행 결과 ]
- 독립적인 인스턴스 확인, 중간에 값을 변경하면 각각 변경됨
2. Class 사용
예제 :
- 이름과 나이를 저장하는 User Class를 작성하고, 두 개의 사용자 참조를 생성해주세요
- 한 참조의 값을 변경한 후, 두 참조가 동일한 값을 공유하는지 확인하세요
[ 실습 코드 ]
import Foundation
// User 클래스 정의 (참조 타입)
class User {
var name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
// 두 개의 사용자 참조 생성
var user1 = User(name: "Alice", age: 25)
var user2 = user1 // user1을 user2에 할당 (같은 참조)
print("Before modification:")
print("User1: \(user1.name), \(user1.age)") // Alice, 25
print("User2: \(user2.name), \(user2.age)") // Alice, 25
// user2를 통해 값 변경
user2.name = "Bob"
user2.age = 30
print("\nAfter modification:")
print("User1: \(user1.name), \(user1.age)") // Bob, 30
print("User2: \(user2.name), \(user2.age)") // Bob, 30
[ 실행 결과 ]
- 참조 형식은 각각의 인스턴스를 생성하여도 참조된 인스턴스 하나의 값을 변경하면 따라서 값이 변경된다
3. Greetable 프로토콜 :
- greet() 메서드를 포함한 Greetable 프로토콜을 정의합니다
- Person Structdhk Robot Class에서 이 프로토콜을 채택하고 구현하세요
- Person은 이름을 활용하여 인사를 출력, Robot은 고유 ID를 활용해 인사를 출력합니다
[ 실습 코드 ]
import Foundation
// Greetable 프로토콜 정의
protocol Greetable {
func greet() -> String
}
// Person 구조체 (값 타입) - 이름을 활용한 인사
struct Person: Greetable {
var name: String
func greet() -> String {
return "Hello, my name is \(name)!"
}
}
// Robot 클래스 (참조 타입) - 고유 ID를 활용한 인사
class Robot: Greetable {
var id: String
init(id: String) {
self.id = id
}
func greet() -> String {
return "Beep boop! I am robot ID: \(id)."
}
}
// 인스턴스 생성 및 테스트
let person = Person(name: "Louis")
let robot = Robot(id: "KKSR-M340")
print(person.greet()) // Hello, my name is Louis!
print(robot.greet()) // Beep boop! I am robot ID: KKSR-M340.
[ 실행 결과 ]
4. 프로토콜 확장 (Extension) :
- Greetable 프로토콜에 기본 구현을 추가하여 greet() 메서드가 기본적으로 "Hello"!"를 반환하도록 하세요
- 기본 구현을 사용하지 않고 고유 인사를 반환하는 Alien Struct를 추가로 구현하세요
[ 실습 코드 ]
import Foundation
// Greetable 프로토콜 정의
protocol Greetable {
func greet() -> String
}
// 프로토콜 확장을 통한 기본 구현 제공
extension Greetable {
func greet() -> String {
return "Hello!"
}
}
// Person 구조체 (기본 구현 사용)
struct Person: Greetable {
var name: String
}
// Robot 클래스 (기본 구현 사용)
class Robot: Greetable {
var id: String
init(id: String) {
self.id = id
}
}
// Alien 구조체 (기본 구현을 오버라이드하여 별도 인사 구현)
struct Alien: Greetable {
var planet: String
func greet() -> String {
return "Greetings, Earthlings! I come from \(planet)."
}
}
// 인스턴스 생성 및 테스트
let person = Person(name: "Alice")
let robot = Robot(id: "XJ-9000")
let alien = Alien(planet: "Mars")
print(person.greet()) // Hello! (기본 구현 사용)
print(robot.greet()) // Hello! (기본 구현 사용)
print(alien.greet()) // Greetings, Earthlings! I come from Mars. (고유 구현)
[ 실행 결과 ]
[ TIL ]
프로토콜 확장을 활용하면 코드의 중복을 줄이면서 유연한 기능 확장이 가능하다.
Struct는 각각의 인스턴스가 독립적이고, Class는 하나의 클래스 인스턴스를 여러 변수에 할당하면 동일한 참조를 공유하게 되기 때문에 인스턴스가 독립적이지 않다
Class 는 참조 타입, Struct는 값 타입이다
클래스는 복잡한 객체 관리 또는 상속이 필요한 경우에 사용하고,
구조체는 독립적인 데이터 또는 간단한 값 저장의 경우에 사용한다
'스파르타 코딩 클럽 - iOS 스타터 6기 > 본 캠프' 카테고리의 다른 글
8. 스파르타 코딩 클럽 - 주석과 print (0) | 2025.03.10 |
---|---|
7. 스파르타 코딩 클럽 - Camel case, Snake case, : 컨벤션 (0) | 2025.03.10 |
5. 스파르타 코딩 클럽 - 네비게이션 및 화면 전환해보기 (0) | 2025.03.05 |
4. 스파르타 코딩 클럽 - 테이블 뷰 만들어보기 (0) | 2025.03.05 |
3. 스파르타 코딩 클럽 - 데이터 관리 (0) | 2025.03.05 |