Swift 기초 문법 - Class(클래스)를 정리하기

Swift의 클래스 역시 구조체처럼 관계가 있는 것들을 묶어서 표현할 때 사용됩니다. 구조체와 마찬가지로 기본적인 구조는 프로퍼티와 메서드로 구성되어있습니다. 구조체를 클래스로 변경이 쉬울 만큼 구현 문법이 동일합니다. 클래스를 알아보고 구조체와 클래스의 차이점에 대해서 알아보겠습니다.

 

Class(클래스) 정의하기

class 클래스 이름 {
	// 프로퍼티
	// 메서드
}

클래스의 간단한 형태입니다 class로 지칭할 수 있으며 propertymethod를 가질 수 있습니다.

class Person {
    var firstName: String = ""
    var lastName: String = "" 
// 따로 initializers를 정의하지 않고 프로퍼티를 초기화 해주어도 됩니다.

   func printMyName() {
        print("My name is \(firstName) \(lastName)")
    }
}

Person를 만들어 보겠습니다. firstnamelastName 프로퍼티를 가지고 있습니다. 저장형 프로퍼티가 초기화가 되어있지 않으면 에러가 발생하게 됩니다.

Class 'Person' has no initializers 초기화를 해야 된다고 알려 주고 있습니다.

해당 Person 클래스의 경우 Stored Property 값이 초기화되어있기 때문에 initializers 생성자를 직접 만들어 주지 않아도 에러가 발생하지 않습니다.

 

Initializer, Deinitializers

class Person {
    var firstName: String
    var lastName: String

    //initializers
    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }
    
    //Deinitializers
    deinit {
        print("인스턴스 소멸")
    }

    func printMyName() {
        print("My name is \(firstName) \(lastName)")
    }
}

let minmong: Person? = Person(firstName: "minmong", lastName: "Ji")
minmong.printMyName()
// 결과 :  My name is minmong Ji
minmong = nil
// 결과 :  인스턴스 소멸

클래스에는 생성자와, 소멸자의 개념처럼 initializersDeinitializers가 있고 생성자, 소멸자로 알아 두면 됩니다. 클래스가 객체화 인스턴스 될 때에 생성자가 실행됩니다. init이라는 메서드를 이용해서 생성자를 만들어 줄 수 있습니다.

 

생성자를 추가하게 되면 인스턴스시 파라미터 값이 필요하게 됩니다. deinit은 클래스 인스턴스가 사라 질 때에 즉 메모리에서 해제되기 직전에 호출됩니다. 또한 매개변수, 반환 값을 가질 수 없습니다. C++에서는 소멸자에서 보통 메모리 해제가 되도록 코드 추가를 하지만 스위프트는 ARC(Auto Reference Counting)을 하기 때문에 필요가 없다고 하네요.

 

Class 상속

상속은 클래스와 구조체의 차이점 중 하나입니다. 상속이란 부모 클래스(Super Class)의 속성과 기능을 자식 클래스(Sub Class)에서 이어받을 수 있게 됩니다. 상속을 할 때에는 A is B라는 개념을 생각해 보면 됩니다.

 

예를 들면 학생은 사람이다. 라는 명제 가있습니다. Student is Person 학생은 사람에 포함이 됩니다. 반대로 사람은 학생이다. 참이 될 경우 모든 사람이 학생은 아니기 때문에 성립할 수가 없게 되며 이렇게 설계가 되었을 경우 나중에 문제가 발생할 수 있습니다.

여기서 우리는 이미 Person이라는 클래스를 가지고 있고 Student라는 클래스를 만들때에Person클래스를 상속할 수 있습니다.

// Person 상속하기
class Student: Person { 
    var grades: [Grade] = []
    
    init(firstName: String, lastName: String, grades: [Grade]) {
        self.grades = grades
        //부모 클래스를 부를 때 super를 사용하면 된다.
        //부모 생성자
        super.init(firstName: firstName, lastName: lastName)
    }
}

var math = Grade(letter: "B", points: 8.5, credits: 3)
var myGrades = Array<Grade>()
myGrades.append(math)

let minmong = Student(firstName: "minmong", lastName: "Ji", grades: myGrades)

Person 클래스를 상속 받고 있는 Student클래스 입니다. 상속을 할 때에는 : 클래스 이름을 통해서 할 수 있습니다. 상속을 하게 되면 Person클래스의 프로퍼티와 메서드를 사용할 수 있습니다. 상속받은 Student클래스 생성자에서 부모의 생성자를 호출해주지 않으면 에러가 발생하게 됩니다.

 

이번에는 학생인minmong이를 인스턴스 했습니다. 학생에는 성적이라는 프로퍼티가 추가되었습니다. 이렇게 미리 만들어진 Person의 프로퍼티와 메서드는 상속을 받게 되면 자식 클래스에서 추가 적인 코드 작업 없이 사용할 수 있게 됩니다.

 

상속의 규칙

  • 자식은 한개의 superclass를 가질 수 있습니다.
  • superclass는 여러 자식을 가질 수 있습니다.
  • 상속의 깊이는 제한이 없습니다.

상속에는 규칙이 있습니다. Swift에서는 하나의 부모 클래스(superclass)를 가질 수 있기 때문에 다중 상속을 받을 수 없습니다. 또한 예시에서 Person 클래스는 또 다른 직업의 부모 클래스가 될 수 있듯이 자식을 둘 수 있는 제한이 없습니다.

class StudentAthlete: Student {
    var minimumTrainingTime: Int = 2
    var trainedTime: Int = 0
    var sports: String = ""
}

상속의 깊이의 제한이 없다는 말은 상속받은 Student 클래스가 다른 클래스의 부모가 될 수 있다는 뜻입니다.

 

designated initialization, convenience initialization

class Student: Person {
    var grades: [Grade] = []
    
    init(firstName: String, lastName: String, grades: [Grade]) {
        self.grades = grades;
        super.init(firstName: firstName, lastName: lastName)
    }
    
    convenience init(grades: [Grade]) {
        self.init(firstName: "minmong", lastName: "ji", grades: grades)
    }
}

 

앞에서 사용한 이니셜라이저(생성자)는 Designated initialization라고 하는데요. Swift에서는 Convenience initialization도 있습니다. 편의 초기화라고 하는데요. 보조 이니셜라이저입니다. 파라미터가 너무 많아질 경우 Designated init의 값들을 기본값으로 설정하고 보조 이니셜라이저를 통해서 인스턴스를 할 수 있습니다.

 

규칙

  • Designated initialization는 자신의 부모의 Designated initialization를 호출해야한다.
  • Convenience initialization는 같은 클래스의 initializers를 꼭 하나 호출해야 한다.
  • Convenience initialization 는 궁극적으로는 Designated initialization를 호출해야 한다.

 

추천글 입니다.

그리드형(광고전용)

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band

댓글

Designed by JB FACTORY