[Swift] 구조체와 클래스

김형근·2024년 7월 20일

[Swift] 문법

목록 보기
8/20

🍎 Swift의 구조체와 클래스

  • Swfit에서는 데이터 모델을 정의하는 데 두 가지 주된 타입인 구조체(Struct)클래스(Class)를 제공합니다.
    이 두 타입은 많은 유사점을 가지고 있지만, 동작 방식과 사용 용도에서 중요한 차이점이 존재합니다. 아래에서 구조체와 클래스의 정의, 프로퍼티 및 메서드, 사용 예제를 살펴보겠습니다.

    프로퍼티에 대해 먼저 알아보겠습니다.

💡 프로퍼티 (Property)

프로퍼티(Property)는 객체지향 프로그래밍에서 클래스나 구조체의 속성을 정의하는 데 사용되는 변수를 의미합니다. 프로퍼티는 객체의 상태를 나타내며, 해당 객체가 가지고 있는 데이터를 저장하는 역할을 합니다.

📚 프로퍼티의 종류

  1. 가변 프로퍼티 (Mutabel Property):
  • 값이 변경될 수 있는 프로퍼티입니다. var 키워드를 사용하여 정의합니다.
  • 예: var age: Int = 20
  1. 불변 프로퍼티 (Immutable Property):
  • 한 번 설정한 후에는 값을 변경할 수 없는 프로퍼티입니다. let 키워드를 사용하여 정의합니다.
  • 예: let birthYear: Int = 2000
  1. 타입 프로퍼티 (Type Property):
  • 클래스나 구조체 자체에 속하는 프로퍼티로 인스턴스가 아닌 타입에 속합니다.
    static 키워드를 사용하여 정의합니다.
  • 예: static var typeCount: Int = 0

📚 프로퍼티의 접근제어

  • 공개 접근 제어(Public): 다른 모듈에서도 접근 가능.
  • 내부 접근 제어(Internal): 같은 모듈 내에서 접근 가능. (기본값)
  • 파일 전용 접근 제어(FilePrivate): 같은 파일 내에서만 접근 가능.
  • 개인 접근 제어(Private): 같은 선언 내에서만 접근 가능.

📚 프로퍼티의 사용 예

struct Person {
    var name: String // 가변 프로퍼티
    let age: Int // 불변 프로퍼티
}

var person = Person(name: "Alice", age: 30)
person.name = "Bob" // 가변 프로퍼티는 수정 가능
// person.age = 31 // 불변 프로퍼티는 수정 불가

🍏 1. 구조체 (Struct)

🧃 1.1 구조체 정의

  • 구조체는 값 타입(Value Type)입니다.
    즉, 구조체의 인스턴스가 다른 인스턴스에 할당되거나 전달될 때, 복사된 값을 가지게 됩니다.
import UIKit

// MARK: - 구조체 정의

struct Sample {
    var mutableProperty: Int = 100 // 가변 프로퍼티
    let immutableProperty: Int = 100 // 불변 프로퍼티

    static var typeProperty: Int = 100 // 타입 프로퍼티

    // 인스턴스 메서드
    func instanceMethod() {
        print("instance Method")
    }

    // 타입 메서드
    static func typeMethod() {
        print("type Method")
    }
}

🧃 1.2 구조체 사용 예제

  • 구조체 인스턴스를 생성하고 프로퍼티를 변경하는 예제입니다.
// MARK: - 구조체 사용

// 가변 인스턴스
var mutable: Sample = Sample()
mutable.mutableProperty = 200 // 가변 프로퍼티는 수정 가능
//mutable.immutableProperty = 200 // 불변 프로퍼티는 수정 불가

// 불변 인스턴스
let immutable: Sample = Sample()
//immutable.mutableProperty = 200 // 불변 인스턴스는 수정 불가
//immutable.immutableProperty = 200 // 불변 인스턴스는 수정 불가

// 타입 프로퍼티 및 메서드 사용
Sample.typeProperty = 300
Sample.typeMethod() // "type Method" 출력

🧃 1.3 학생 구조체 예제

  • 학생 구조체를 정의하고 사용하는 예제입니다.
// MARK: - 학생 구조체

struct Student {
    var name: String = "unknown"
    var `class`: String = "Swift"

    static func selfIntroduce() {
        print("학생타입입니다.")
    }

    func selfIntroduce() {
        print("저는 \(self.class)\(name)입니다.")
    }
}

Student.selfIntroduce() // "학생타입입니다." 출력

var geuni: Student = Student()
geuni.name = "geuni"
geuni.class = "Swift"
geuni.selfIntroduce() // "저는 Swift 반 geuni입니다." 출력

let jina: Student = Student()
// 불변 인스턴스이므로 프로퍼티 값 변경 불가
// 컴파일 오류 발생
// jina.name = "jina"
jina.selfIntroduce() // "저는 Swift 반 unknown입니다." 출력

🍏 2. 클래스 (Class)

🧃 2.1 클래스 정의

  • 클래스는 참조 타입(Reference Type)입니다. 클래스의 인스턴스가 다른 인스턴스에 할당되거나 전달될 때, 참조가 복사됩니다.
    따라서 두 인스턴스가 동일한 데이터를 참조할 수 있습니다.
import UIKit

// MARK: - 클래스 정의

class Sample {
    var mutableProperty: Int = 100 // 가변 프로퍼티
    let immutableProperty: Int = 100 // 불변 프로퍼티
    
    static var typeProperty: Int = 100 // 타입 프로퍼티
    
    // 인스턴스 메서드
    func instanceMethod() {
        print("instance method")
    }
    
    // 타입 메서드
    // 재정의 불가 타입 메서드 - static
    static func typeMethod() {
        print("type method - static")
    }
    
    // 재정의 가능 타입 메서드 - class
    class func classMethod() {
        print("type method - class")
    }
}

🧃 2.2 클래스 사용 예제

  • 클래스 인스턴스를 생성하고 프로퍼티를 변경하는 예제입니다.
// MARK: - 클래스 사용

var mutableReference: Sample = Sample()
mutableReference.mutableProperty = 200 // 가변 프로퍼티 수정 가능
//mutableReference.immutableProperty = 200 // 불변 프로퍼티 수정 불가

let immutableReference: Sample = Sample()
//immutableReference.mutableProperty = 200 // 불변 인스턴스는 수정 불가
//immutableReference.immutableProperty = 200 // 불변 인스턴스는 수정 불가

// 타입 프로퍼티 및 메서드 사용
Sample.typeProperty = 300
Sample.classMethod() // "type method - class" 출력

🧃 2.3 학생 클래스 예제

  • 학생 클래스를 정의하고 사용하는 예제입니다.
// MARK: - 학생 클래스

class Student {
    var name: String = "unknown"
    var `class`: String = "Swift"
    
    class func selfIntroduce() {
        print("학생타입입니다.")
    }
    
    func selfIntroduce() {
        print("저는 \(self.class)\(name)입니다.")
    }
}

Student.selfIntroduce() // "학생타입입니다." 출력

var geuni: Student = Student()
geuni.name = "geuni"
geuni.class = "Swift"
geuni.selfIntroduce() // "저는 Swift 반 geuni입니다." 출력

let jina: Student = Student()
jina.name = "jina"
jina.selfIntroduce() // "저는 Swift 반 jina입니다." 출력

💡 3. 구조체와 클래스의 차이점

📍 3.1 값 타입 vs 참조 타입

  • 구조체(Struct): 값 타입(Value Type)으로, 인스턴스가 복사될 때 모든 프로퍼티의 값도 함께 복사됩니다. 따라서, 구조체의 인스턴스를 다른 변수에 할당하거나 함수의 매개변수로 전달할 때 새로운 복사본이 생성됩니다.
  • 클래스(Class): 참조 타입(Reference Type)으로, 인스턴스가 복사될 때 참조만 복사됩니다.
    즉, 여러 변수나 상수에서 동일한 인스턴스를 참조할 수 있으며, 한 인스턴스에서 변경이 발생하면 모든 참조에서 영향을 받습니다.

📍 3.2 상속

  • 구조체: 상속을 지원하지 않습니다. 즉, 구조체는 다른 구조체로부터 상속받을 수 없습니다.
  • 클래스: 상속을 지원합니다. 클래스는 다른 클래스로부터 상속받아 기능을 확장하고, 메서드를 재정의할 수 있습니다.

📍 3.3 메모리 관리

  • 구조체: 스택(Stack) 메모리에 저장되며, 메모리 관리가 상대적으로 간단합니다.
  • 클래스: 힙(Heap) 메모리에 저장되며, 참조 카운팅(reference counting) 방식으로 메모리 관리를 합니다. 이로 인해 메모리 관리가 더 복잡해질 수 있습니다.

📍 3.4 성능

  • 구조체: 값 타입이기 때문에 복사 비용이 발생할 수 있지만, 작은 데이터 구조에서는 성능이 우수할 수 있습니다.
  • 클래스: 참조 타입으로, 복사 대신 참조를 사용하기 때문에 대규모 데이터 구조에서 더 효율적일 수 있습니다.

💡 4. 언제 구조체를 사용하고 언제 클래스를 사용해야 할까?

📍 4.1 구조체를 사용하는 경우

  1. 값으로서의 의미가 있는 데이터: 데이터가 고유한 값을 가지며, 다른 인스턴스와 독립적으로 존재해야 하는 경우.
  2. 단순한 데이터 모델: 프로퍼티가 적고, 기능이 단순한 경우
  3. 불변성을 유지해야 하는 경우: 데이터가 변경되지 않도록 보장해야 할 때.
  4. 상속이 필요하지 않은 경우: 상속을 사용할 필요가 없는 경우

📍 4.2 클래스를 사용하는 경우

  1. 공유 상태가 필요한 경우: 여러 인스턴스가 동일한 데이터에 접근하고, 이를 변경할 필요가 있는 경우
  2. 상속을 활용해야 하는 경우: 기존 클래스를 기반으로 새로운 클래스를 만들고 기능을 확장해야 할 때
  3. 복잡한 데이터 모델: 프로퍼티가 많거나, 메서드가 복잡한 경우.
  4. 동적 메모리 관리가 필요한 경우: 객체의 생명 주기를 관리해야 할 때.
profile
꾸준히 기록하기

0개의 댓글