swift 기초 문법 <5>

구찌댕댕이·2022년 6월 22일
0

swift 기초 문법

목록 보기
5/12
post-thumbnail

클래스

클래스는 붕어빵 틀. 객체는 붕어빵. -> 클래스가 있어야 객체지향언어
클래스로 부터 만들어진 객체를 인스턴스라고 한다.(swift에서는 객체 = 인스턴스)
청사진이나 설계사의 그림이 건물이 완성된 후의 모습을 나타내고 있는 것 처럼 클래스는 객체가 생성되었을 때 어떠한 모습을 보일 것인지를 정의
클래스 = 자동차
프로퍼티(특성,데이터,속성) = 문, 핸들, 바퀴, 의자
메소드(행위, 조작) = 움직인다, 정차한다, 감속한다 -> 어떠한 일을 하고 어떠한 속성이 있는지 정의

  • 프로퍼티 : 클래스 내에 포함되는 변수와 상수
  • 인스턴스 메소드 : 객체가 호출하는 메소드
  • 타입(클래스) 메소드 : 클래스가 호출하는 메소드

코딩 : class 클래스이름: 부모 클래스 { 프로퍼티 / 인스턴스 메소드 / 타입 메소드 }

클래스에 프로퍼티 추가하기

반드시 초기값이 있어야 한다.
init을 이용하여 초기화 하면 초기값은 없어도 가능하다.
옵셔널 변수 or 상수로 선언하여 초기값이나 nil 할당.
저장(stored) 프로퍼티와 계산(computed) 프로퍼티가 있다.

class Woman {
    var age : Int = 0 // age와 weight는 저장 프로퍼티라서 반드시 초기값이 있어야 한다.
    var weight : Double!  // 옵셔널로 프로퍼티 선언
    var name : String?  // 옵셔널로 선언하면 언래핑 해줘야 함
}

클래스에 메소드 추가하기

인스턴스 메소드는 인스턴스가 호출하며, 함수처럼 작성하면 된다.

타입(클래스) 메소드는 클래스 레벨에서 동작하는 것으로, 클래스의 새로운 인스턴스를 생성하는 것과 같은 동작
타입 메소드는 인스턴스 메소드와 동일한 방법으로 선언하지만 앞에 class 또는 static을 붙인다.
class 키워드로 만든 클래스 메소드는 자식 클래스에서 override 가능 하다.

class Woman {
    var age : Int = 2   // stored 프로퍼티
    var weight : Double! = 3.5  // stored 프로퍼티
    
    func display() {  // 인스턴스 메소드 -> 인스턴스에서 동작
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    class func cM() {  // 타입 메소드 -> 클래스에서 동작 / 자식 클래스에서 override 가능
        print("cM은 클래스 메소드 입니다.")
    }
    static func scM() {  // 타입 메소드 -> 클래스에서 동작
        print("scM은 클래스 메소드(static)")
    }
 }

인스턴스 만들기

class Woman {
    var age : Int = 2  
    var weight : Double! = 3.5  
    
    func display() {  // 인스턴스 메소드
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    class func cM() {  // 타입 메소드
        print("cM은 클래스 메소드 입니다.")
    }
    static func scM() {  // 타입 메소드
        print("scM은 클래스 메소드(static)")
    }
    
var x : Int = 0 // Int x 변수를 선언 하듯이
var kim : Woman = Woman() // 클래스 Woman 인 객체 kim을 선언
                          // 일반 변수 선언과는 다르게 ' = Woman() ' 써줘야 함
                          // ' : Woman ' 은 생략 가능 -> var kim = Woman()
                          // 눈에 보이지 않는 default initializer 를 호출하는것
print(kim.age)
kim.display()  // 인스턴스 메소드는 인스턴스가 호출
Woman.cM()  // 클래스 메소드는 클래스가 호출
Woman.scM()  // 클래스 메소드는 클래스가 호출

인스턴스 초기화하기 : init()

클래스, 구조체, 열거형(enum)에서 인스턴스가 생성되는 시점에서 해야할 초기화 작업
인스턴스가 만들어지면서 자동 호출됨
designated initailizer : 모든 프로퍼티를 다 초기화 시키는 생성자
소멸자 : 인스턴스가 사라질 때 자동 호출 -> deinit{}

코딩 : init() { }

class Woman {
    var age : Int = 2   // stored 프로퍼티
    var weight : Double! = 3.5  // stored 프로퍼티

    func display() { 
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    init(yourAge: Int, yourWeight: Double) {
        age = yourAge
        weight = yourweight
    }   // designated initializer
    class func cM() {  // 타입 메소드 -> 클래스에서 동작 / 자식 클래스에서 override 가능
        print("cM은 클래스 메소드 입니다.")
    }
    static func scM() {  // 타입 메소드 -> 클래스에서 동작
        print("scM은 클래스 메소드(static)")
    }
}
var kim : Woman = Woman(yourAge: 10, yourWeight: 20.5)
// init을 하나라도 만들면 default init은 사라진다
// 따라서 var kim : Woman = Woman() 은 오류가 뜨게 됨
// init을 만들면 stored 프로퍼티인 age 와 weight는 초기값이 없어도 가능
kim.display()

self

현재 클래스 내의 메소드나 프로퍼티를 가리킬 때 사용
self.메소드 / self.프로퍼티
같은 이름의 매개변수와 구분하기 위해 반드시 사용

class Man {
    var age : Int
    var weight : Double
    func display() {
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    init(age: Int, weight: Double) {
        self.age = age  // self.age 는 클래스의 프로퍼티
        self.weight = weight  // age 는 init의 매개변수
    }
}
var kim = Man(age:10, weight: 20.4)
// 1. age 와 weight의 값은 클래스 Man의 init의 매개변수로 할당
// 2. init의 매개변수 값을 클래스의 프로퍼티로 할당
// 3. 할당된 프로퍼티로 메소드 display 실행
kim.display()

computed 프로퍼티

var 로 선언해야한다
계산 프로퍼티는 프로퍼티가 설정되거나 검색되는 시점에서 계산 또는 파생된 값

  • 값을 리턴하는 getter 메소드
  • 값을 대입하는 setter 메소드

setter가 없으면 get{ } 는 생략 가능
set(newValue) { } 매개변수명은 newValue가 default. (생략가능)

코딩 : var 이름 : 타입 { get { return 내용 } set(newValue) { 대입 내용 } }

class Man {
    var age : Int
    var weight : Double
    var manAge : Int {  // computed 프로퍼티
        get { // setter가 없으면 생략 가능
            return age-1  //manAge프로퍼티 호출시 age의 값
        }
        set(USAAge) { // newValue 대신 USAAge를 매개변수로 사용
            age = USAAge + 1  // manAge에 값 할당시 age의 값
        }
    }
    func display() {
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    init(age: Int, weight: Double) {
        self.age = age
        self.weight = weight
    }
}
var kim = Man(age:10, weight: 20.4)
kim.display()
print(kim.manAge)  // 9 -> 클래스 Man의 manAge로 get의 리턴값
print(kim.age)  // 10
kim.manAge = 3  // 클래스 Man의 manAge로 set(USAAge)에 값을 할당
print(kim.age)  // 4-> set(USAAge)로 연산된 값이 age 프로퍼티에 할당

method overloading : 생성자 중첩

매개변수의 개수와 자료형이 다르고 이름만 같은 함수를 여러개 정의

class Man {
    var age : Int
    var weight : Double = 3.5  // 두번째 init 때문에 초기값을 넣어줘야한다.
    var manAge : Int {
        get {
            return age-1
        }
        set(USAAge) {
            age = USAAge + 1
        }
    }
    func display() {
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    init(age: Int, weight: Double) {  // 첫번째 init
        self.age = age
        self.weight = weight
    }
    init(age: Int) {  // 두번째 init
        self.age = age  // weight 는 클래스 Man의 default 값을 사용
    }
}
var kim = Man(age:10, weight: 20.4)
kim.display()  // 나이 = 10, 몸무게 = 20.4
var kim2 = Man(age:20)
kim2.display()  // 나이 = 20, 몸무게 = 3.5

UIImage 클래스의 init()함수 overloading

앱에서 이미지 데이터를 관리하는 클래스인 UIImage는 15개의 init()가 overloading되어 있다.
init?(named: String) 의 init을 사용하여
let myImage: UIImage = UIImage(named: "apple.png")!
myImage 라는 인스턴스(객체)를 생성

init? : 실패 가능한 생성자

  1. apple.png 파일이 없으면 인스턴스를 만들 수 없다.
  2. nil 값도 저장할 수 있으려면 init? 을 사용하여 옵셔널 값이 리턴 되도록 한다.
  3. init? 로 만든 인스턴스는 옵셔널형이기 때문에 언래핑해야 하므로 마지막에 '!' 가 붙는다

init? or init! 사용 하지만 일반적으로 '?' 를 많이 사용한다
오류 상황에 nil을 리턴하는 조건문이 있음

class Man {
    var age : Int
    var weight : Double
    
    func display() {
        print("나이 = \(age), 몸무게 = \(weight)")
    }
    init?(age: Int, weight: Double) {
        if age <= 0 {
            return nil
        } else {
        self.age = age
        }
        self.weight = weight
    }
}
var kim : Man? = Man(age:1, weight: 20.4) // 옵셔널 인스턴스 선언
if let kim1 = kim { // 옵셔널 바인딩
    kim1.display()
}
if let kim2 = Man(age:2, weight: 5.5) {
    kim2.display()  // 인스턴스 생성과 동시에 옵셔널 바인딩
}
var kim3 : Man = Man(age: 2, weight: 4.4)!
kim3.display()  // 인스턴스 생성과 동시에 강제 언래핑
var kim4 : Man? = Man(age: 8, weight: 0)
kim4!.display() // 옵셔널 인스턴스를 사용시 강제 언래핑

// 나이가 nil 값일 때
var kim : Man? = Man(age: -1, weight: 3.5)
if let kim1 = kim {
    kim1.display()  // nil이 리턴되어 아무런 값도 나오지 않는다
}
if let kim2 = Man(age: 0, weight: 5.5) {
    kim2.display()  // nil이 리턴되어 아무런 값도 나오지 않는다
}
var kim3 : Man = Man(age: 0, weight: 1.1)!
kim3.display()  // nil을 강제로 풀어버려 crash가 생긴다
                // 강제 언래핑은 위험함

출처 : https://www.youtube.com/channel/UCM8wseo6DkA-D7yGlCrcrwA

profile
개발자를 꿈꾸는 사람 입니당

0개의 댓글