카테고리 없음

class 와 struct 의 차이점 3

양시관 2024. 3. 4. 12:42
  1. class에서는 상속이 가능한데, struct에서는 왜 불가능한가?
    사실 저번 포스팅의 개념에서 모두 가져와도 과언이 아닐정도로 저번 포스팅에서 전체적으로 다 다뤘다. 
    그래서 이번에는 프로토콜이라는 방법으로 가능하게 만들어주는 개념을 알아보려고한다. 
    • 값 형식과 참조 형식: Swift에서 struct는 값 형식이며 복사에 의해 전달됩니다. 이는 각 인스턴스가 고유하며 독립적인 상태를 유지한다는 것을 의미합니다. 반면, class는 참조 형식이며, 참조에 의해 전달됩니다. 이는 여러 참조가 동일한 인스턴스를 가리킬 수 있음을 의미합니다. 상속은 참조 형식에서 더 자연스럽게 작동하며, 값 형식에서는 의미가 덜 합니다.
    • 메모리 관리: struct 인스턴스는 스택 메모리에 저장되고, class 인스턴스는 힙 메모리에 저장됩니다. 스택 메모리는 할당과 소멸이 빠르지만, 상속과 같은 복잡한 기능을 지원하기에는 제한적입니다. 힙 메모리는 더 유연하지만 관리가 더 복잡합니다.
    • 설계 목적: Swift에서 struct는 작고 간단한 데이터 구조를 모델링하기 위해 사용됩니다. 예를 들어, 좌표계, 설정, 또는 간단한 데이터 캡슐화에 적합합니다. class는 더 복잡한 데이터 모델이나 상속을 필요로 하는 경우에 사용됩니다.
    • 성능: 값 형식은 참조 카운팅 오버헤드 없이 복사될 수 있으며, 이는 종종 더 나은 성능을 의미합니다. 상속을 도입하면 이러한 성능 이점이 손상될 수 있습니다.
      일단 이러한 이유로 class 만 상속이 가능하다.

      대신 ! 
      Swift에서는 struct 대신 프로토콜(Protocols)을 사용하여 유사한 기능을 구현할 수 있다. 프로토콜은 struct, class, enum 등 Swift의 모든 타입에 채택할 수 있으며, 상속과 비슷한 방식으로 코드를 재사용하고 인터페이스를 정의할 수 있게 도와준다고 생각하면 된다.
      프로토콜은 타입에 특정 기능이나 속성이 구현되어 있음을 보장해주면서 다형성을 제공하는 방법 중 하나하고 생각하면 된다.
      따라서, Swift에서는 struct 사용이 간결하고 예측 가능한 형식을 위한 것이며, 상속이 필요한 경우 class 프로토콜을 사용하는 것이 일반적이지만 이런 상속의 대체제가 어떤 방식으로 굴러가고 어떻게 단점을 극복하게 되었는지도 알아볼 필요가 있다.

      프로토콜이 상속의 단점을 극복하는방법
      • 타입 안전성: 프로토콜은 어떤 타입이 특정 인터페이스 또는 API를 준수한다는 것을 보장한다라는 약간 우리와의 약속인데  상속과 달리, 프로토콜은 다중 상속의 문제없이 여러 프로토콜을 동시에 채택할 수 있다.
      • 유연성: 프로토콜은 struct, class, enum 등 어떤 타입에도 채택할 수 있어, 다양한 타입에 공통의 기능을 제공할 수 있습니다. 이는 클래스 기반 상속이 제공할 수 없는 유연성을 의미를 하게된다. 예를 들면 어떤 부분에서도 프로토콜을 쓸수있는데 그만큼 유연하다! 라는 의미로 생각하면 될것같다. 
      • 재사용성: 프로토콜은 코드 재사용을 촉진한다. 사실 이이야기는 당연한 이야기이다. 왜냐면 프로토콜이라는 것을 일종의 약속이라고 생각하게되면 인스턴스등을 모두 맞춰놓을것인데 이 하나만으로도 재사용을 하기위한 소스를 짜려고 노력하지않아도 자동으로 된다는 느낌이다.
      일급 시민(First-class citizen)일급 함수가 상속의 단점을 보완하는 방법

      일단 일급시민은  함수가 속한다고 알고있으면 되는데 함수형식의 언어에 장점은 너무 많다. 이는 밑에다가 정리를 하겠다.
      • 재사용성과 유연성: 함수를 변수에 할당하거나 다른 함수의 인자로 전달할 수 있기 때문에, 고차 함수(higher-order functions)와 같은 기능을 사용하여 코드의 재사용성과 유연성을 높일 수 있게된다.
      • 모듈성: 작은 함수로 프로그램을 나눔으로써, 각 부분을 독립적으로 개발하고 테스트할 수 있다. TDD 를 사용한 테스트도 기본구조가 함수를 테스트하는것이니까 말 다했다. 이는 큰 클래스 계층구조를 만드는 것보다 유지보수가 쉽고 오류를 찾기가 더 쉽습니다.
      • 추상화: 함수를 사용하여 코드의 특정 부분을 추상화하면, 구현 세부사항을 숨기고 사용자에게 더 간단한 인터페이스를 제공할 수 있다.