[swift] 클래스 (class) & 상속 (inheritance)

Snyong·2023년 9월 28일

swift

목록 보기
8/10
post-thumbnail

class 만들기

  • class 키워드를 이용해서 생성
  • struct와는 다르게 memberwise initializer 제공되지 않음
class Dog {
    var name:String
    var breed: String
    
    init(name:String, breed:String) {
        self.breed=breed
        self.name=name
    }
}

let milk = Dog(name: "milk", breed: "Collie")

milk.name // milk
milk.breed // Collie

class inheritance (클래스 상속)

  • classstruct 의 차이중 하나는 class 는 상속을 제공한다는 점
  • 상속을 이용하면 기존 클래스를 이용해 신규 클래스를 생성할 수 있음
  • 기존 클래스 → 부모(parent) 또는 슈퍼(super) 클래스
  • 새로 생성한 클래스 → 자식(child) 클래스
class Dog {
    var name:String
    var breed: String
    
    init(name:String, breed:String) {
        self.breed=breed
        self.name=name
    }
}

class Collie:Dog {
    init(name:String) {
        super.init(name: name, breed: "Collie")
    }
}

let milky = Collie(name: "milky")
milky.name // milky
milky.breed // Collie

overriding method

  • 자식 클래스는 부모 클래스의 메소드를 그대로 쓸 수 있음
  • 자식 클래스는 부모 클래스의 메소드를 변형해서 쓸수 있음 (overriding)
class Dog {
    var name:String
    var breed: String
    
    init(name:String, breed:String) {
        self.breed=breed
        self.name=name
    }
    
    func bark() {
        print("bow wow")
    }
}

class Collie:Dog {
    init(name:String) {
        super.init(name: name, breed: "Collie")
    }
    
    override func bark() {
        print("wal wal")
    }
}


let nooni = Dog(name: "Nooni", breed: "poodle")
let milky = Collie(name: "milky")

nooni.bark() // bow wow
milky.bark() // wal wal

final class

  • 클래스 상속을 허용하지 않아야 할때가 있음
  • final 키워드를 이용하여 클래스를 선언하면, 상속 가능하지 않음
final class Dog {
    var name:String
    var breed: String
    
    init(name:String, breed:String) {
        self.breed=breed
        self.name=name
    }
    
    func bark() {
        print("bow wow")
    }
}

class Collie:Dog {
    init(name:String) {
        super.init(name: name, breed: "Collie")
    }
    
    override func bark() {
        print("wal wal")
    }
}


let nooni = Dog(name: "Nooni", breed: "poodle")
let milky = Collie(name: "milky")

nooni.bark() // bow wow
milky.bark() // wal wal

copying object

  • struct 와 같은 value type 은 복사하면 새로운 객체를 만듦
    → 새로 복사된 객체를 변경해도 원래 객체에 영향을 주지 않음
  • class 와 같은 reference type 은 복사해도 새로운 객체를 만들지 않음
    → 같은 객체를 포인팅하고 있음 (마치 포인터처럼)
    → 새로 복사된 객체의 변경사항이 원래 객체에도 영향을 준다
class StudentClass {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}

struct StudentStruct {
    var name: String
    
    init(name: String) {
        self.name = name
    }
}


var studentClass1 = StudentClass(name: "Jacob")
var studentClass2 = studentClass1

studentClass2.name = "Jay"
studentClass1.name // Jay
studentClass2.name // Jay

var studentStruct1 = StudentStruct(name: "Jacob")
var studentStruct2 = studentStruct1

studentStruct2.name = "Jay"
studentStruct1.name // Jacob
studentStruct2.name // Jay

deinitializer

  • classstruct 의 차이중 하나는 classdeinitializer 가 있음
  • 해당 인스턴스가 메모리에서 해제될때 (없어질때) 호출됨
class Human {
    var name: String
    
    init(name: String) {
        self.name = name
        print("initialize instance")
    }
    
    deinit {
        print("deintilize instance: \(name)")
    }
    
    func printName() {
        print("my name: \(self.name)")
    }
}

func createJohn() {
    let john = Human(name: "John")
    john.printName()
}

createJohn()

mutability

  • classstruct 와 다르게 reference type 이여서 상수로 선언하더라도, 프로퍼티가 var로 선언해놓았으면 변경이 가능하다!
  • 따라서 mutating 키워드를 쓸 필요가 없다
  • 프로퍼티를 변경 불가능하게 하려면 let 으로 선언하면 된다
class Human {
    var name: String
    
    init(name: String) {
        self.name = name
        print("initialize instance")
    }
    
    deinit {
        print("deintilize instance: \(name)")
    }
    
    func printName() {
        print("my name: \(self.name)")
    }
    
    func updateName(to name: String) {
        self.name = name
    }
}

let sean = Human(name: "Sean")
sean.name
sean.updateName(to: "Snyong")
sean.name

0개의 댓글