본문 바로가기
FRONT-END/iOS

객체지향 프로그래밍 이해하기 - 클래스와 구조체편

by 랄라J 2023. 7. 26.

객체지향 프로그래밍

  • 의미있는 데이터 묶음으로 만드는 것

 

객체지향 4대 특징

  • 추상화 : 모델링 | 실체들의 공통적 특성을 뽑아내서 클래스로 정의하는 것
  • 캡슐화 : 데이터 캡슐화 | 연관이 있는 속성과 메서드를 하나의 클래스로 묶어서 활용하는 것
    • 은닉화 : 캡슐화를 하면 접근제어자를 사용해 객체 외부에서 객체 내부 데이터의 접근 통제가 가능함
  • 상속성: 재사용성, 확장 | 부모 클래스의 속성과 메서드를 자식 클래스가 그대로 물려받는 것
  • 다형성: 사용편의, 동적바인딩 | 하나의 객체가 여러가지 타입의 형태로 저장할 수 있고, 다양한 메서드의 형태로 동작 가능함
    • 오버라이딩, 오버로딩

 

클래스와 인스턴스의 관계

  • 클래스는 붕어빵 틀
  • 붕어빵 틀에 재료를 넣고 만들어내는 것이 인스턴스
    재료를 무엇을 넣느냐에 따라 팥붕어빵, 슈크림붕어빵이 되느냐는 달라지지만 붕어빵은 달라지지 않음
    붕어빵 틀에서 만들어졌기 때문
  • Swift에서는 인스턴스를 객체라고 부름
    인스턴스 : 클래스와 구조체를 바탕으로 실제 메모리에 저장한 것

 

클래스

  • 클래스는 변수와 함수를 선언할 수 있음
  • 선언된 변수는 속성(property), 함수는 메서드(method)라고 함

 

클래스(Class)와 구조체(Struct)의  차이점

  • 메모리 저장 방식의 차이
  • 구조체는 값 형식, 인스턴스 데이터를 모두 스택에 저장
  • 클래스는 참조 형식, 인스턴스 데이터를 모두 힙에 저장하고, 해당 힙을 가리키는 메모리 주소 값을 가진 변수가 스택에 저장
  • 값을 복사 시 구조체는 새로운 복사본을 생성(다른 메모리 공간 사용)하지만, 클래스는 저장된 주소를 전달
  • 클래스만 유일하게 상속이 가능한 구조 

 

초기화

  • 모든 저장 속성을 초기화해야함
    • 옵셔널타입을 가진 변수의 경우는 반드시 초기화값이 있을 필요는 없음 nil로 초가화 됨
  • self 키워드는 클래스/구조체 내에서 해당 인스턴스(자기자신)을 가르킴
  • class에 같은 인스턴스인지를 비교하는 연산자 ===, !==
  • 오버로딩을 지원해 다양한 파라미터 조합으로 생성자 여러개 구현 가능함
class Friend {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
    	self.name = name
        self.age = age
    }
}

var suji = Friend(name: "suji", age: 20)
var hana = Friend(name: "hana", age: 24)
// 위와 동일 var hana = Friend.init(name: "hana", age: 24)

 

클래스와 구조체를 사용하는 이유

  • 사용하려는 모델의 설계
    • DTO(Data Transfer Object) 관련된 데이터를 한 곳에 담는 역할
    • DAO(Data Access Object) 데이터 처리(비즈니스 로직)
    • Helper Option : 유틸리티
  • 애플이 설계해놓은 클래스와 구조체를 잘 사용하기 위함

 

언제 클래스, 구조체를 사용하는가

  • 메모리에 오래 저장 없이, 상속이 필요없는 경우 구조체 사용
    • 연관된 데이터들을 단순히 캡슐화 하는 것이 목적인 경우
    • 캡슐화한 데이터를 참조해서 사용하는 것보다 복사하는 것이 더 효율적인 경우
    • 구조체에 저장된 저장 속성이 값 타입이며 참조하는 것보다 복사하는 것이 더 합당한 경우
  • 메모리에 오래 저장, 상속이 필요한 경우
    • 해당 모델을 serialize해서 전송하거나 파일로 저장해야하는 경우
  • 반드시 클래스가 필요한 경우가 아니면 구조체를 씀 (apple도 struct 사용 권장)
    • 클래스가 구조체보다 여러가지 면에서 속도가 느림

 

속성

  • 저장속성(Stored Properties)
    • 값이 저장되는 일반적인 속성을 말함
    • 저장속성은 각 속성자체가 고유한 메모리를 가짐
    • 변수나 상수로 선언 가능함
    • 객체 초기화 시 각 저장 속성은 반드시 값을 가져야 함
  • 지연 저장 속성(Lazy Stored Properties)
    • 저장 속성 앞에 lazy 키워드를 붙여 사용하고 var로만 선언 가능
    • 처음부터 고유한 메모리를 가지는 것이 아닌 접근하는 순간 메모리 공간을 만들고 초기화함
    • 따라서, 선언 시점에 기본값을 저장시켜야함
    • 메모리 공간을 많이 차지하는 경우, 다른 속성을 이용해야하는 경우 사용함
  • 계산 속성 (Computed Properties)
    • 관련이 있는 두가지 메소드를 한번에 구현할 수 있는 장점이 있음
      • 겉모습은 속성 형태인 메서드임 (인스턴스에 메모리 공간이 할당되어 있지 않음)
    • get block은 반드시 구현해야함, set block은 선택 구현 가능
      • get만 구현된 경우 get-only property 또는 read-only property라고 함
      • set block의 파라미터는 newV alue로 사용할 수도 있고 명칭을 지정할 수도 있음
    • var로만 선언 가능하고 자료형을 반드시 선언해줘야 함
  • 타입 속성 (Type Properties)
    • 저장 타입 속성과 계산 타입 속성으로 구분할 수 있음
    • 저장 타입 속성
      •  항상 초기값이 있어야 함 
      • 모든 인스턴스가 동일하게 가져야하는 보편적인 속성이거나, 공유해야하는 속성에 가까운 속성을 선언
      • Dog라는 클래스의 인스턴스들의 종은 Dog라는 것 또는 Circle이라는 클래스의 인스턴스가 생성되어도 원의 속성 중 파이 등의 변하지 않는 속성들을 저장하고 사용할 수 있음 / 또는 클래스가 몇개 생성되었는지를 확인하기 위해 init 시 count를 증가시키는 등으로 활용할 수 있음
      • 지연 속성의 성격을 가짐,  여러 쓰레드에서 접근하는 경우에도 한번만 초기화되도록 보장됨
    • 계산 타입 속성
      • var 키워드로만 선언 가능
      • 상속에서 재정의가 가능한 경우 class 키워드 사용
      • 메서드이기 때문에 메모리 공간이 할당되어있지 않음
    •  static 또는 클래스인 경우 class 키워드를 사용해 선언하는 방식으로 선언된 타입속성을 확인하고 싶을때는 인스턴스에 접근해서는 확인할 수 없기 때문에 타입(클래스명 또는  구조체명)로 접근해야 확인할 수 있음

 

속성 감시자 (Property Observer)

  • willSet, didSet 키워드를 사용해 구현하며 일반적으로 하나만 구현함, 실무에서는 didSet을 많이 사용
    • willSet : 값이 저장되기 직전에 호출됨, 바뀔 값이 파라미터로 전달됨 (기본적으로 newValue 파라미터 제공)
    • didSet : 값이 변경된 직후에 호출됨, 바뀌기 전 값이 파라미터로 전달됨 (기본적으로 oldValue 파라미터 제공)
  • 저장 속성 변경을 감시한다고 생각하면 이해가 편함

 

메서드

  • 인스턴스 메서드 : 가장 기본적인 메서드, 오버로딩 지원
  • 타입 메서드 : static 또는 class 키워드를 붙여 선언하는 메서드, 타입 자체 성격에 가까운 메서드
  • 서브스크립트
    • Array[0], Dictionary["A"]와 같이 대괄호를 사용하는 문법을 칭하는 용어
    • subscript 키워드를 이용해 구현 func 키워드는 생략함
    • subscript(index: Int) -> String { get {} set {} }
    • 파라미터와 리턴형 생략 불가하며, get block만 선언해 read-only로 선언 가능

 

접근 제어

  • private 키워드를 사용해 선언
  • 코드 내부 세부 구현 내용을 숨길 수 있어 은닉화가 가능함
  • 코드의 영역을 분리시켜 효율적 관리 가능
  • 컴파일러가 해당 변수가 어느 범위에만 사용되는지 인지가 가능해  컴파일 시간이 줄어듬
728x90

댓글