원래 아침 출근 전에 운동으로 수영을 꾸준히(?) 했었는데, 앱스쿨 하고 업무하는 것 보다 더 빡센 강도와 교육시간 외에도 특강과 회고와 개인공부로 인해서 수영을 가야 하는데 못갔었다. 하지만 더 이상 미루면 수영을 중단하게 될 것 같아서 오늘은 꼭 가기로 마음먹었고 성공했다ㅎㅎ
[강사님 책추천]
- 프로그래머의 뇌
https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=285967039
https://www.youtube.com/watch?v=JHbF83tlVz0
1. 오전일정 : Playgorund 놀아보기
2. 오후일정 : (일정설명)
[클래스(class), 객체(object), 인스턴스(instance)]
현실세계의 붕어빵을 만들기로 하였다.
객체 : 붕어빵 (내가 현실 세계에 있는 것을, 소프트웨어상에서 만들고자 하는 것)
클래스 : 붕어빵을 만들기 위한 틀 그리고
인스턴스 : 붕어빵 틀로 찍어낸 각각의 붕어빵
팥붕어빵과 슈크림붕어빵은 같은 객체(붕어빵)를 가진다.
하지만 팥붕어빵과 슈크림붕어빵은 각각 팥과 슈크림을 가지고 있는 붕어빵이기 때문에 다른 인스턴스이다.
<메서드>
1. 객체란?
- 객체(또는 인스턴스)는 소프트웨어 앱을 구축하는 블록을 쉽게 사용하고 재사용할 수 있는 독립적인 기능 모듈이다.
- 작업을 수행하기 위한 객체나 인스턴스에서 접근되고 호출되는 속성(property)과 함께 함수로 객체가 구성된다.
- 객체를 구성하는 데이터 변수와 함수를 포괄적으로 클래스 멤버(class member)라고 한다.
2. 클래스란?
- 클래스는 객체가 생성될 때의 모습을 정의한다.
- Swift의 3가지 타입 중 하다이다.
3. 클래스 선언하기
- 객체를 인스턴스화하기 전에 객체에 대한 '틀'을 정의해야 한다.
- 새로운 Swift 클래스를 선언할 때 새롭게 만드는 클래스가 어떤 부모 클래스(parent class)에서 파생되었는지를 지정하고 클래스에 포함할 프로퍼티와 메서드를 정의한다.
- 선언부의 프로퍼티(property) 부분은 이 클래스 내에 포함될 변수와 상수를 정의하며, Swift에서 변수나 상수를 선언할 때와 동일한 방법을 선언한다.
- 인스턴스 메서드(instance method)와 타입 메서드(type method)부분은 이 클래스에서 호출되는 메서드들과 클래스 인스턴스들을 정의한다.
- 본질적으로 이것들은 특정 작업을 수행하는 클래스 고유의 함수이다.
4. 클래스 인스턴스 만들기
- 클래스의 메소드는 변수를 통해서 접근이 되지 않고, 클래스명을 통해서 직접 호출해야 한다.
class BankAccount{
var accountBalance: Float = 0
var accountNumber: Int = 0
func displayBalance(){
print("Number \(accountBalance)")
print("Current balance is \(accountNumber)")
}
class func getMaxBalance() - >Float { //class랑 static 두 개의 키워드를 동일한 목적으로 같이 쓸 수 있음(상속 재정의 가능 여부에 따라 구별 필요)
return 100000.00
}
}
//오류
var account = BalanceAccount()
account.displayBalance()
//클래스 자체만의 고유 메서드를 사용할 때는 아래와 같이 사용 필요
let balance: Float = BankAccount.getMaxBalance()
https://sujinnaljin.medium.com/swift-class-func-vs-static-func-7e6feb264147
5. 클래스 인스턴스 선언하기와 초기화하기
class BankAccount{
var accountBalance: Float = 0
var accountNumber: Int = 0
func displayBalance(){
print("Number \(accountBalance)")
print("Current balance is \(accountNumber)")
}
class func getMaxBalance() - >Float { //class랑 static 두 개의 키워드를 동일한 목적으로 같이 쓸 수 있음(상속 재정의 가능 여부에 따라 구별 필요)
return 100000.00
}
}
//클래스 자체만의 고유 메서드를 사용할 때는 아래와 같이 사용 필요
let balance: BankAccount = BankAccount()
5. 클래스 인스턴스 초기화하기와 소멸하기
- 클래스는 생성하는 시점에 해야 할 초기화 작업이 있을 수 있다.
- 이 작업은 클래스의 init 메서드 안에서 구현해야 한다.
- 반대로, Swift 런타임 시스템에 의해 클래스 인스턴스가 없어지기 전에 해야 할 정리 작업은 클래스 안에 소멸자(deinitializer)를 구현하면 사용할 수 있다.
class BankAccount{
var accountBalance: Float = 0
var accountNumber: Int = 0
init(number: Int, balance: Float){ //초기화 작업
accountBalance = balance
accountNumber = number
}
deinit{
//필요한 정리 작업을 여기서 수행
}
class func getMaxBalance() - >Float { //class랑 static 두 개의 키워드를 동일한 목적으로 같이 쓸 수 있음(상속 재정의 가능 여부에 따라 구별 필요)
return 100000.00
}
}
var account1: BankAccount = BankAccount(
balance: 400.54
number: 12345123
)
6. 메서드 호출하기와 접근하기
점 표기법 : 클래스 인스턴스 다음에 점을 찍고 그 뒤에 프로퍼티나 메서드 이름을 써서 인스턴스 변수에 접근하거나 인스턴스 메서드를 호출하게 된다.
<사용법>
클래스인스턴스.프로퍼티명
클래스인스턴스.인스턴스메서드()
점 표기법을 사용하면 인스턴스 프로퍼티에 값을 설정할 수도 있다.
//클래스는 위 코드 참고
account1.accountBalance = 6778.98 //class 외부에서 인스천스 프로퍼티 접근
- 타입 메서드(getMaxBalance) 역시 점 표기법을 이용하여 출력된다.
- 다만 주의할 점은 클래스 인스턴스가 아니라 클래스에서 호출되어야 한다. 클래스는 참조됨.
//클래스는 위 코드 참고
var maxAllowed = BankAccount.getMaxBalance()
7. 저장 프로퍼티와 연산 프로퍼티
- Swift의 클래스 프로퍼티는 저장 프로퍼티와 연산 프로퍼티로 나뉜다.
- 저장 프로퍼티는 상수나 변수에 담기는 값이다.
* 앞 예제들에서 사용된 프로퍼티는 모두 저장 프로퍼티다. - 연산 프로퍼티는 프로퍼티에 값을 설정하거나 가져오는 시점에서 어떤 계산이나 로직에 따라 처리된 값이다.
- 연산 프로퍼티는 게터(getter)를 생성하고 선택적으로 세터(setter) 메서드를 생성하며, 연산을 수행할 코드가 포함된다.
class BankAccount{
var accountBalance: Float = 0
var accountNumber: Int = 0
var incomeFeeOfThisMonth: Float {
get {
return accountBalance * 0.01
}
}
init(number: Int, balance: Float){ //초기화 작업
accountBalance = balance
accountNumber = number
}
deinit{
//필요한 정리 작업을 여기서 수행
}
class func getMaxBalance() - >Float { //class랑 static 두 개의 키워드를 동일한 목적으로 같이 쓸 수 있음(상속 재정의 가능 여부에 따라 구별 필요)
// class의 멤버 변수(프로퍼티), 멤버 함수도 호출, 대입하는 행위는 불가능
// 반대로, class(static) 멤버 변수, class 멤버 함수 호출은 가능
// 함수 몸체 내에서 변수 선언 등은 모두 가능
return 100000.00
}
func printIncomeFeeOfThisMonth() {
print("이번달의 예상 이자는 \(accountBalance * 0.01)")
}
}
var account1: BankAccount = BankAccount(
balance: 400.54
number: 12345123
)
var max1 = BankAccount.getMaxBalance() // OK
var max2 = account1.getMaxBalance() // OK
account1.printIncomeFeeOfThisMonth() // OK : class 이름으로도 호출 가능한 static member function 입니다
BankAccount.printIncomeFeeOfThisMonth() // compile error! : instance 만 호출 가능합니다
account1.incomeFeeOfThisMonth = 123.567
8. 지연 저장 프로퍼티
- 복잡한 클로저의 경우는 초기화 작업이 리소스와 시간을 많이 사용ㅇ하게 될 수 있다. 하
- 클로저를 이용하여 선언하면 해당 프로퍼티가 코드 내에서 실제로 사용되는지랑 상관 없이 클래스의 인스턴스가 새성될 때마다 초기화 작업이 수행될 것이다.
- 프로퍼티를 최초로 접근할 때만 초기화 작업을 하는 것이다.
- lazy로 프로퍼티를 선언하면 가능
9. self 사용하기
- 현재 클래스 인스턴스에 속한 메서드나 프로퍼티를 가리킬 때 프로퍼티와 메서드 앞에 self를 붙인다.
- 하지만 Swift로 프로그래밍할 때는 self를 사용할 필요가 없다. 왜냐하면 self는 프로퍼티와 메서드에 대한 참조를 디폴트로 간주하기 때문이다.
class MyClass{
var myNumber = 1
func addTen(){
self.myNumber += 10
}
}
10. 프로토콜
- 클래스가 구조적으로 올바르게 되지 위하여 Swift 클래스가 반드시 따라야 할 특징 규칙은 기본적으로 없다.
- 하지만 다른 클래스와 함께 작업을 할 때는 특정 조건에 맞춰야 한다.
- IOS SDK(Software Developer Kit)의 다양한 프레임워크와 함께 동작하는 클래스를 만들 때는 더욱 그렇다.
- 클래스가 충족하는 최소한의 요구사항을 정의하는 규칙들의 집합을 프로토콜이라고 한다.
- 프로토콜은 protocol 키워드를 이용하여 선언되며, 클래스가 반드시 포함해야 하는 메서드와 프로퍼티를 정의한다.
- 어떤 클래스가 프로토콜을 채택했으나 모든 프로토콜의 요구사항을 충족하지 않는다면, 그 클래스가 해당 프로토콜을 따르지 않는다는 에러가 발생하게 된다.
- 클래스 기본틀(존재자체를 정의)을 정리해 놓은 것이라고 이해하고, 나중에 클래스에서 세부적으로 구현을 한다고 생각하면 되겠죠...?
protocol MessageBuilder{
var name: String{get} //getter 만들어내라
func buildMessage() -> String
}
class MyClass: MessageBuilder {
var name: String //get, set 존재하지만 생략됨
init(name: String){
self.name = name
}
func buildMessafe() -> String{
"Hello" + name
}
}
오늘의 코딩과제 : 계좌 만들기
import Foundation
// 은행 계좌에 대한 클래스
class BankAccount {
//프로퍼티
//1. 계좌번호
//2. 남은 잔고 데이터
var accountNum : Int = 0
var accountBal : Float = 0.0
let fees : Float = 3.3
init(number: Int, balance: Float){
accountNum = number
accountBal = balance
}
//현재 잔액에서 수수료를 빼는 값을 주고받을 때 새로 계산해주는 연산 프로퍼티
var balLessFees: Float {
get {
return accountBal - fees
}
set {
accountBal = newValue - fees //이해가 안되는데용... newValue 선언 안해도 되나요... 왜죠...
}
}
//계좌 정보와 잔고를 출력하는 메소드
func displayInformation() {
print("Account Number = \(accountNum)")
print("This account have \(accountBal)$")
}
//최대로 담을 수 있는 금액을 알려주는 클래스 메소드
//인스턴스를 따로 만들어 초기화하지 않아도 실행해서 확인하게 해줘야 한다.
class func getMaxBal() -> Float {
return 100000.0
}
}
//var kittyAccount = BankAccount()
//kittyAccount.accountNum = 111222333444
//kittyAccount.accountBal = 120.8
//kittyAccount.displayInformation()
var marimoAccount: BankAccount = BankAccount(number: 5423329874819472, balance: 92848.3)
marimoAccount.displayInformation()
print("Balance Less Fees = \(marimoAccount.balLessFees)$")
marimoAccount.balLessFees = 854.6
print("Balance Less Fees = \(marimoAccount.balLessFees)$")
오늘의 코딩과제 : 계좌 만들기 with 프로토콜
import Foundation
protocol Device {
var name: String { get }
var color: String { get set }
func buildMemoTxt() -> String //기기의 이름과 색상 정보가 담긴 메모 문자열 만들기
}
class myComputer: Device {
var kind: String
var date: String
var price: Int
//프로토콜 관련
var name: String = "MacBook Air"
var color: String = "Rose Gold"
init(kind: String, date: String, price: Int) {
self.kind = kind
self.date = date
self.price = price
}
func displayComputer() -> String{
return "종류 : \(kind), 구매일자 : \(date), 가격 : \(price)"
}
//프로토콜 관련
func buildMemoTxt() -> String{
return "기기명 : \(name), 색상 : \(color)"
}
}
var myMac: myComputer = myComputer(kind: "MacBook", date: "2022-04-01", price: 100 )
print("Information: \(myMac.displayComputer()) \(myMac.buildMemoTxt())") //객체의 모든 정보(프로퍼티) 출력 - 종류, 구매일자, 가격 등
3. 오늘의 리뷰
오늘 수업의 감상은 아래 그림으로 대체한다...