Jerry's Bakery

[iOS] Swift Class와 Struct 본문

개발/iOS

[iOS] Swift Class와 Struct

_Jerry 2021. 10. 11. 22:41

안녕하세요 Jerry입니다.

 

Swift에서 Class와 Struct에 대해 알아보겠습니다.

 

iOS를 공부하면서 정리하는 것이기 때문에 미흡한 점이 있을 수 있습니다. 부족한 점에 대해 댓글 남겨주시면 감사하겠습니다.

 

Class란?

class는 객체지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메서드를 정의하는 일종의 툴입니다.

객체를 정의하기 위한 멤버 변수와 메서드로 구성되어 있습니다.

Struct란?

struct는 class와 동일하게 데이터를 구조화하여 관리하는 데 사용되고, 문법도 유사합니다.

Swift에서 데이터 타입과 열거형(enum)은 모두 struct 타입으로 선언되어 있습니다.

아래 그림에서 Int타입이 struct인 것을 확인할 수 있습니다.

 

Class와 Struct의 공통점

  • 저장된 변수를 가질 수 있습니다(ex. var isBool: Bool)
  • 계산된 변수를 가질 수 있습니다(ex. var body: some View { Text() })
  • let(상수)를 가질 수 있습니다
  • function을 가질 수 있습니다

 

Class와 Struct의 차이점

  Class Struct
메모리 타입 Reference Type Value Type
사용되는 프로그래밍 함수형 프로그래밍에서 사용 객체지향 프로그래밍에서 사용
값 초기화 모든 var에 대해 Memberwise Initializer 지원 init 을 통한 초기화만 가능
변경가능성 데이터가 변경할 것인지에 대해 명시해줘야 함 변경은 어느곳에서나 가능
상속 가능하지만, Swift에서는 한개의 class만 상속할 수 있음 불가능

 

값 초기화

Animal struct를 생성하고, cat 변수에 Animal struct를 할당했습니다.

var 변수에 있는 struct의 값이 올바르게 할당되었음을 확인할 수 있습니다.

struct를 class로 변경하면 어떻게 될까요?

두 가지 오류가 발생합니다.

Class에서 "Animal class에서는 Initializer가 존재하지 않는다"라고 오류를 발생하고 있습니다.

Class의 인스턴스를 생성하는 부분에는 "'Animal'에는 액세스 할 수 있는 Initializer가 없기 때문에 생성할 수 없다"라는 오류를 발생하고 있습니다.

왜 그럴까요?

위 표에서 나타나 있는 것처럼 struct에서는 값을 초기화할 때는 멤버와이즈 초기화(Memberwise Initializer)가 가능하기 때문에 별도의 초기화 메서드가 필요하지 않지만, class에서는 별도의 초기화 메서드가 필요하기 때문에 이와 같은 오류를 발생시킵니다.

이러한 문제를 해결하기 위해서는 Animal class의 인스턴스를 생성할 때 초기값을 설정할 수 있도록 init 즉, 생성자를 구현해야 합니다.

생성자를 추가하고 오류가 사라졌음을 확인할 수 있습니다.

메모리 타입(Value vs Reference)

위의 표에서 struct는 value타입이고, class는 Reference 타입이라고 했습니다.

cat2 변수를 선언해, cat변수를 그대로 할당한 후 cat의 age를 4로 변경한 후 두 변수 모두 타입을 확인해보겠습니다.

cat의 나이만 변경했을 뿐인데 cat2의 나이도 함께 변경되는 것을 확인해볼 수 있습니다.

 

왜 그럴까요?

class는 인스턴스화 해서 변수에 할당될 때 포인터라고 불리는 "메모리 주소"를 전달합니다. 인스턴스는 메모리의 별도 공간에 저장되어 있고 변수에 그 공간의 위치만 알려주는 것입니다. 그렇기 때문에 아래 코드를 실행하게 되면 cat변수와 cat2 변수 모두 같은 메모리 주소 공간을 가리켜 한 공간을 두 변수가 공유하게 되는 것입니다.

var cat2 = cat

그렇기 때문에 cat의 값을 변경하면 cat2의 값이 변하게 됩니다.

 

 

두 번째로 Animal class를 struct로 변경하여 확인해보겠습니다.

이번에는 cat의 나이를 4살로 변경했는데도 cat2의 값이 변경되지 않고 3살이라는 것을 확인할 수 있습니다.

 

왜 그럴까요?

struct는 메모리 타입이 Value 타입이기 때문입니다.

아까 class를 설명할 때는 메모리 주소를 전달한다고 말씀드렸습니다. 하지만 struct는 Value값만을 넘겨줍니다.

cat 변수에 Animal struct를 할당하게 되면 cat 변수의 메모리 공간에 struct가 생성이 됩니다. 그리고 아래 코드가 실행되면 cat2 변수의 메모리 공간에 cat의 메모리 공간을 "복사"하게 됩니다.

var cat2 = cat

그렇게 되면 각 변수의 메모리 공간에 다르게 저장되어 있기 때문에 cat의 나이를 변경하더라도 cat의 정보를 변경하는 것이기 때문에 cat2의 나이에 영향을 주지 않게 됩니다.

 

 

상속

우선 class를 먼저 상속해보겠습니다.

Animal class를 선언하고, Cat class는 Animal class를 상속받습니다.

하지만 Swift의 class는 하나의 class만 상속받을 수 있습니다.

아래 코드에서 Cat class는 Animal과 A class 2개를 상속받았습니다.

그러자, Animal과 A class로부터 다중 상속을 받았다고 오류가 발생하게 되었습니다.

Swift에서는 단일 상속만 가능하고, 추가적으로 상속을 받으려면 프로토콜을 사용해야 합니다.

Struct를 상속해 보겠습니다.

struct를 상속하자, non-protocol 타입인 Animal struct를 상속할 수 없다고 오류를 발생하는 것을 확인할 수 있습니다.

 

Comments