오늘도 복습! 하나씩 짚으면서 보니까 좋더라
지난번엔 뇌를 빼놓고 들었던 것 같다 하하.
import UIKit
// 참조 타입인 클래스 예시
class Person {
var name: String //name이라는 프로퍼티 가진 Person 클래스
//클래스 내부의 모든 프로퍼티는 값을 가지고 있어야 하는데, 지금은 값이 없다.
//이때
init(name1: String) { //init 키워드 사용해 이니셜라이저 만들어준다(=인스턴스 생성)
self.name = name1 //self 키워드는 현재 인스턴스 자신을 나타낸다.
//뒤에 있는 name1은 파라미터 값(=외부에 있는 name1)을 받은 것!
//간단히 설명하면, self.name = name1은 "나(현재 객체)의 이름은 파라미터로 전달받은 name1이다"라는 의미이다.
}
}
var person1 = Person(name1: "Alice") //init은 메서드지만, init 자체를 함수명으로 사용하지는 않고
//Class 이름을 사용한다. 그리고 init 뒤의 파라미터 적어준다.
// 여기서 person1은 Person 클래스의 인스턴스를 참조하고 있다.
var person2 = person1 //참조 복사
//person2에 person1을 할당하면, person2도 동일한 인스턴스를 참조한다.
//Person1과 Person2는 같은 메모리 주소, 같은 객체를 가리키게 된다.
person2.name = "Bob"
print(person1.name) // 출력: Bob
print(person2.name) // 출력: Bob
// 예시 1
class Name {
var name: String
init(name: String) {
self.name = name
}
func sayMyName() {
print("my name is \(name)")
}
}
let song : Name = Name(name: "song")
print(song.name) // song
song.sayMyName() // my name is song
song.name = "kim"
song.sayMyName() // my name is kim
// 예시 2
class Person1 {
var name: String // 저장 프로퍼티
var introduction: String { // 계산 프로퍼티
return "제 이름은 \(name)입니다."
}
init(name: String) {
self.name = name
}
}
// Person 객체 생성
let person3 = Person1(name: "Alice")
print(person3.introduction) // 출력: 제 이름은 Alice입니다.
// 예시 3
class Counter {
var count = 0 // 저장 프로퍼티
func increment() { // 인스턴스 메서드
count += 1
}
static func reset() { // 타입 메서드
print("카운터를 초기화합니다.")
}
}
// Counter 객체 생성
let counter1 = Counter()
counter1.increment()
counter1.increment()
print(counter1.count) // 출력: 2
// 호출 방식: 인스턴스 생성한 다음에 함수 호출한다
Counter.reset() // 출력: 카운터를 초기화합니다.
// 호출 방식: Counter 클래스에 직접 접근해 reset을 호출한다./
//Struct
//값 타입(Structures구조체, Enumerations열거형, 기본데이터타입)
//init 구현하지 않아도 ㅡeberwise Initializer. 제공
// 값 타입인 구조체 예시
struct Point {
var x: Int
var y: Int
}
var point1 = Point(x: 5, y: 10)
var point2 = point1 // 값 자체를 복사, point1의 인스턴스는 그대로 유지
point2.x = 15
print(point1) // 출력: Point(x: 5, y: 10)
print(point2) // 출력: Point(x: 15, y: 10)
//상속 불가능
//인스턴스로 만들어서 사용 가능
struct Coffee {
var name: String?
var size: String?
func brewCoffee() -> String {
if let name = self.name {
return "\(name) ☕️ 한 잔 나왔습니다"
} else {
return "오늘의 커피 ☕️ 한잔 나왔습니다"
}
}
}
let americano = Coffee(name: "아메리카노")
print (americano.brewCoffee())
// 출력값: 아메리카노 ☕️ 한 잔 나왔습니다
let any = Coffee()
print (any.brewCoffee())
// 따로 init()을 구현하지 않아도 자동으로 생성자를 받습니다.
// Memberwise Initializer 예시
struct ShoppingListItem {
let name: String?
let quantity: Int
var purchased = false
}
let item1 = ShoppingListItem(name: "칫솔", quantity: 1)
let item2 = ShoppingListItem(name: "치약", quantity: 1, purchased: true)
let item3 = ShoppingListItem(name: nil, quantity: 1, purchased: true)
import UIKit
//Enum 열거형
//값으로 이루어진 그룹 같은 타입으로 선언
//타입 안정성 보장
// 간단한 열거형 선언
// 케이스만 저장
// 케이스가 명확한 경우
enum CompassDirection {
case north
case south
case east
case west
}
// 열거형의 인스턴스 생성 및 사용
var direction = CompassDirection.north //(enum명).(케이스명) 사용해서 인스턴스 생성!
var anotherDirection = direction // 값 복사
direction = .east // 값을 변경해도 anotherDirection에는 영향이 없음
// 값만 복사되고 참조 복사가 된게 아니기 때문!
print(direction) // 출력: east
print(anotherDirection) // 출력: north
// 연관 값을 가진 열거형 선언
// 케이스에 특정 값 연결해서 저장
enum Trade {
case buy(stock: String, amount: Int)
case sell(stock: String, amount: Int)
case hold
}
// 열거형의 인스턴스 생성 및 사용
let trade1 = Trade.buy(stock: "AAPL", amount: 100)
let trade2 = Trade.sell(stock: "GOOG", amount: 50)
let trade3 = Trade.hold
// switch 문을 사용하여 연관 값 추출
func processTrade(trade: Trade) { //Ennum의 타입 = 커스텀한 타입
switch trade { //trade가 무엇인지를 switch로 판단
case .buy(let stock, let amount): //let 키워드 선언해주면, let tarde1 뒤에 따라오는 연관값들과 매칭된다.
print("Buy \(amount) shares of \(stock).")
case .sell(let stock, let amount):
print("Sell \(amount) shares of \(stock).")
case .hold:
print("Hold this position.")
}
}
// 각 열거형 케이스에 따라 다른 동작 수행
processTrade(trade: trade1) // 출력: Buy 100 shares of AAPL.
processTrade(trade: trade2) // 출력: Sell 50 shares of GOOG.
processTrade(trade: trade3) // 출력: Hold this position.
// 자주 사용하는 메서드
enum CompassPoint {
case north
case south
case east
case west
}
// 한 케이스 선언 방법
var directionToHead = CompassPoint.west
directionToHead = .east
// 활용 예시 1
directionToHead = .south
switch directionToHead {
case .north:
print("북쪽")
case .south:
print("남쪽")
case .east:
print("동쪽")
case .west:
print("서쪽")
}
// 출력값: "남쪽"
// allCases
enum Beverage: CaseIterable { //CaseIterable 프로토콜 채택
case coffee, tea, juice
}
let numberOfChoices = Beverage.allCases.count //CaseIterable 사용하면 allCases 사용 가능
print("\(numberOfChoices) 잔 주문 가능합니다.")
// 출력값: 3잔 주문 가능합니다
/*
//옵셔널
//옵셔널도 enum이기 때문에 switch로 손쉽게 사용 가능하다!
// 실제 Optional의 정의
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
/// The absence of a value. //값이 없는 상태
///
/// In code, the absence of a value is typically written using the `nil`
/// literal rather than the explicit `.none` enumeration case.
case none
/// The presence of a value, stored as `Wrapped`. //값이 있는 상태
case some(Wrapped)
print(Optional.none == nil) // true //nil은 실제 인스턴스이다. 메모리 값을 가지고 있다.
*/
코드를 적어주셔서 다시 한번 복습했어요. 열거형에 CaseIterable 내용이 있었나? 찾아보니 있네요. 다시 공부해야겠어요. ㅜ