[ Swift ] 구조체(struct)와 클래스(class)

스위프트의 구조체와 클래스에 대해 공부하기!
김보람's avatar
Oct 07, 2024
[ Swift ] 구조체(struct)와 클래스(class)

구조체는 값을 저장하고, 그와 관련된 함수를 정의할 수 있는 데이터 타입으로 클래스와 비슷하다.

[구조체와 클래스의 차이]

/

구조체

클래스

타입

Value Type

그 인스턴스의 값이 복사되어 완전한 독립적인 형태를 가지게 됨

Reference Type
객체의 잠조가 전달되어 복사되지 않고 동일한 객체를 여러 변수가 공유하게 됨

상속

상속을 지원하지 않음

클래스가 다른 클래스로부터 기능을 상속받고, 상속된 기능을 확장하거나 재정의 할 수 있음

메모리 관리

스택 메모리에 저장 됨
값이 복사되기 때문에 *ARC에 의한 메모리관리가 필요없음

힙 메모리에 저장되며, *ARC를 사용해 메모리를 관리함. 그로인해 더 많은 메모리와 리소스를 사용하게 된다

불변성

let으로 선언된 인스턴스의 모든 프로퍼티는 변경할 수 없음

let으로 전언되었더라도 그 인스턴스의 프로퍼티는 수정가능하다

Mutating

구조체의 메서드가 인스턴스 프로퍼티를 변경하려면 mutating키워드를 사용해야함

mutating 키워드 사용없이 자유롭게 변경 가능함

동일성 비교

실제 값을 비교함, 같은 값을 가지고 있으면 동일한것으로 간주

참조 위치를 비교함, 두 객체가 같은 메모리 위치를 참조하는지를 확인하므로 값이 같더라도 참조가 다르면 다른 객체로 간주 됨

용도

객체를 모델링할때에 사용되며 주로 작은 데이터를 다룸

데이터가 공유되거나 객체 간 상속이 필요한 경우 계정 관리, 네트워크 연결 처리 등에 적합

*ARC(Automatic Reference Counting)는 객체의 참조 횟수를 자동으로 계산하여, 참조 횟수가 0이 되면 해당 객체를 메모리에서 해제하는 방식으로 메모리를 관리함


[구조체]

할당 시 복사되므로 원본과 복사본은 서로 독립적인 상태를 가지며 서로에게 영향을 주지 않는다.

  • struct 키워드를 사용하여 정의되며, 내부에는 프로퍼티(변수나 상수)와 메서드(함수)를 가질 수 있다

  • 기본형태

struct 구조체명 {
   프로퍼티나 메서드등을 작성
}
  • 사용

    //구조체 정의
    struct Sample {
        var mutableProperty : Int = 100
        let immutableProperty : Int = 100
        
        static var typeProperty : Int = 100
        
        func instanceMethod(){
            print("instance method")
        }
        
        static func typeMethod(){
            typeProperty += 1
            print("type method")
        }
    }
    • 인스턴스를 var로 생성해줄 경우 가변 인스턴스로 내부 프로퍼티를 변경할 수 있으나, 프로퍼티 선언자체에서 let 키워드로 선언되었다면 그 프로퍼티는 변경할 수 없다

    //가변 인스턴스
    var newSample :Sample = Sample()
     
    newSample.mutableProperty = 50
    newSample.immutableProperty = 50 //에러
    • 인스턴스를 let으로 생성할 경우 내부의 값을 가변 프로퍼티로 선언했다 하여도 변경 할 수 없다.

    //불변 인스턴스
    let newSample :Sample = Sample()
     
    newSample.mutableProperty = 50 //에러
    newSample.immutableProperty = 50 //에러
    • static

      • static은 인스턴스완 독립적으로 구조체 자체에 속하는 프로퍼티와 메서드를 정의하는 데 사용됨

      • static은 인스턴스를 생성하지 않고 타입 자체에서 접근할 수 있다

      • 인스턴스마다 고유한 값을 가지는 다른 프로퍼티나 메서드와 다르게 구조체 전체에서 하나의 값만을 유지한다

      newSample.typeProperty //에러 반환
      
      Sample.typeMethod()
      print(Sample.typeProperty) //출력 101
    • 예제 코드

      struct Menu {
          var name : String = "아메리카노"
          var price : Int = 4000
          
          static func menuIntroduction () -> Void {
              print("메뉴는 아래와 같습니다.")
          }
          func menuIntroduction () -> Void{
              print("\(name)의 가격은 \(price)입니다.")
          }
        
      }
      
      
      Menu.menuIntroduction()
      var coffee : Menu = Menu()
      coffee.name = "바닐라크림 콜드블루"
      coffee.price = 6500
      coffee.menuIntroduction()
      
      // 출력
      // 메뉴는 아래와 같습니다.
      // 바닐라크림 콜드블루의 가격은 6500입니다.

[클래스]

참조 타입으로, 객체를 여러 변수나 함수에서 참조할 때 같은 객체를 공유하므로 서로에게 영향을 미친다

  • class 키워드를 통해 정의한며, 내부에는 프로퍼티(변수나 상수)와 메서드(함수)를 가질 수 있다

  • 기본형태

    class 클래스명 {
       //구현부
    }
  • 사용

    //클래스를 정의
    class Person {
        var name: String
        var age: Int
        
        
        init(name: String, age: Int) {
            self.name = name
            self.age = age
        }
    }
    //할당하여 사용
    let person1: Person = Person(name: "영희", age: 19)
    print(person1.name) //영희 출력
    print(person1.age) // 19 출력
    • 상속

      //위에 정의한 Person의 타입을 상속받아
      //해당 타입을 가지면서 자기만의 타입을 더 추가할 수 있다
      
      class Adult : Person {
          var job : String
          var maritalStatus : Bool
          
          init(job: String, maritalStatus: Bool, name:String,age:Int) {
              self.job = job
              self.maritalStatus = maritalStatus
              super.init(name: name, age: age)
              
          }
          
      }
      
      let adult1 :Adult = Adult(job: "주부", maritalStatus: true, name: "김영희", age: 36)
      
      print(adult1.job)  //주부 출력
      print(adult1.name) //김영희 출력
    • 참조 타입으로 참조 위치를 공유하기 때문에 할당한 후 값을 바꾸면 따라 바뀜

      class Person {
          var name: String
          var age: Int
          
          
          init(name: String, age: Int) {
              self.name = name
              self.age = age
          }
      }
      
      
      let person1 : Person = Person(name: "박철수", age: 23)
      let person2 = person1
      
      person1.age = 36
      print(person2.age)

Share article

b0-0d