궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFT/Grammar

Swift : 기초문법 [프로퍼티#4 - 타입 프로퍼티]

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

본 게시글은 yagom님과Zedd0202님의 게시글을 참고하여 작성되었습니다.

 

타입 프로퍼티

이제 까지 알아본 프로퍼티 라는 개념은 모두 Type을 정의하고 해당 타입의 인스턴스가 생성되었을 때 사용할 수 있는 인스턴스 프로퍼티라고 생각 하면 된다.

 

즉, 인스턴스 프로퍼티는 특정한 구조체, 클래스에 속하는 저장 프로퍼티연산 프로퍼티 이다.

 

각각의 인스턴스가 아닌 타입 자체에 속하는 프로퍼티를 타입 프로퍼티라고 한다.

 

인스턴스의 생성 여부와 관계없이 타입 프로퍼티의 값은 하나이다. 타입 프로퍼티는 모든 타입이 사용할 수 있는 상수 프로퍼티 또는 글로벌 변수 프로퍼티처럼 특정 타입의 모든 인스턴스에 공통적인 값을 정의하는데 유용하다. 

 

저장 타입 프로퍼티는 변수 또는 상수로 선언 가능

연산 타입 프로퍼티는 변수로만 선언 가능

저장/연산 타입 프로퍼티

반드시 초깃값(기본값)을 설정해야 하며 lazy(지연) 연산된다. 왜냐하면 초기화할 때 타입 자체에는 저장 타입 프로퍼티에 값을 할당할 이니셜라이저가 없기 때문. 지연 저장 프로퍼티와는 조금 다른 게 다중 스레드 환경 이어도 단 한 번만 초기화되기 때문에 lazy 키워드를 사용할 필요가 없다.

 

정리해보자면 

  • 프로퍼티를 타입 자체에 연결하는 게 타입 프로퍼티!
  • 타입 프로퍼티에는 저장/연산 타입 프로퍼티가 존재!
  • 저장 타입 프로퍼티는 변수/상수 일 수 있고, 무조건 기본값을 설정해야 함! 그리고 처음 액세스 할 때는 기본적으로 지연 연산이 되기 때문에 lazy 키워드를 사용할 필요 없음!
  • 연산 타입 프로퍼티는 무조건 변수로 선언되어야 함!

Swift에서 타입 프로퍼티는 타입 정의의 일부로 타입의 외부 중괄호 안에 쓰이고, 각 타입 프로퍼티는 명시적으로 지원하는 타입으로 범위가 지정되게 된다.

 

static 키워드를 사용하여 타입 프로퍼티를 정의할 수 있다. 만약 클래스 타입에 대한 연산 타입 프로퍼티의 경우에는 class 키워드를 사용해 서브클래스가 슈퍼 클래의 의 구현부를 재정의(override)할 수 있다.

 

struct SomeStructure {
    
    static var storedTypeProperty = "Some value." //저장 타입 프로퍼티 기본값을 줌
   
    static var computedTypeProperty: Int { //연산 타입 프로퍼티
        return 1
    }
}

SomeStructure이라는 구조체가 있고 그아래 static 키워드가 있는 변수 storedTypeProperty가 기본값과 함께 구현되어 있다. 이 부분이 저장 타입 프로퍼티이고 그아래는 타입 프로퍼티가 된다.

 

저장 타입 프로퍼티를 보면 저장 인스턴스 프로퍼티와는 다르게 기본값이 있다(저장 인스턴스 프로퍼티는 기본값을 주지 않아도 됐었다).  그리고 무조건 변수 var로 선언되어야 한다!

저장 타입 프로퍼티 enum

enum SomeEnumeration {  
    static var storedTypeProperty = "Some value." //저장 타입 프로퍼티
    static var computedTypeProperty: Int { //연산 타입 프로퍼티
        return 6
    }
}

어? 저장 인스턴스 프로퍼티에서는 분명 '클래스, 구조체에서만 사용된다'라고 알고 있었는데 저장 타입 프로퍼티는 열거형 enum에서도 사용 가능하다는 걸 알 수 있다. 열거형에서도 기본값을 정해줬고 역시 변수 var로 선언되어있다.

 

연산 타입 프로퍼티는 get만  구현되어 있다.

클래스 타입에 대한 연산 프로퍼티

위에서 말한 '클래스 타입에 대한 연산 타입 프로퍼티의 경우에는 class 키워드를 사용해 서브클래스가 슈퍼 클래의 의 구현부를 재정의(override)할 수 있다.' 에 대한 예제를 보자면

class SomeClass {
    static var storedTypeProperty = "Some Value"
    static var computedTypeProperty: Int {
        return 10
    }
    //연산 타입프로퍼티
    //static 키워드가 아닌 class 키워드를 사용함.
    //서브클래스가 슈퍼클래스 구현을 재정의(overrid)함!
    class var overrideableComputedTypeProperty: Int {
        return 200
    }
}

여기서 overrideableComputedTypePropertyclass 키워드가 붙었기 때문에 연산 타입 프로퍼티가 되겠고, 서브클래스가 슈퍼클래스 구현을 재정의 한다고 했으니 SomeClass를 상속받은 어떠한 클래스는 class 키워드가 붙은 overrideableComputedTypeProperty 연산 타입 프로퍼티를 재정의 할 수 있다는 뜻이다.

class SomeClass {
    static var storedTypeProperty = "Some Value"
    static var computedTypeProperty: Int {
        return 10
    }
    class var overrideableComputedTypeProperty: Int {
        return 200
    }
}

//SomeClass라는 슈퍼클래스를 상속받은 ChildSomeClass에서 
//class 키워드가 붙은 overrideableComputedTypeProperty를 재정의 할 수 있다.
class ChildSomeClass: SomeClass {
    override static var overrideableComputedTypeProperty: Int {
        return 323
    }
}

재정의 하는 것이기 때문에 반드시 override 키워드를 붙여줘야 하고, 만약 class 키워드가 붙지 않은 연산 타입 프로퍼티를 재정의 하려고 하면 위와 같이 Error가 난다.

class SomeClass {
    static var storedTypeProperty = "Some Value"
    static var computedTypeProperty: Int {
        return 10
    }

    static var overrideableComputedTypeProperty: Int {
        return 200
    }
}

class ChildSomeClass: SomeClass {
    override static var overrideableComputedTypeProperty: Int {
        return 323  // error! cannot override statice var
    }
}

타입 프로퍼티는 인스턴스를 생성하지 않고도 사용할 수 있고, 타입에 해당하는 값이다. 그래서 인스턴스에 접근할 필요 없이 타입 이름만으로도 프로퍼티를 사용할 수 있다.

class AClass {
    //저장 타입 프로퍼티
    static var typeProperty: Int = 0
    
    //저장 인스턴스 프로퍼티
    var instanceProperty: Int = 0 {
        didSet {
            //self.typeProperty는
            //Aclass.typeProperty와 같은 표현임
            Self.typeProperty = instanceProperty + 10
        }
    }
    //연산 타입 프로퍼티
    static var typeComputedProperty: Int {
        get {
            return typeProperty
        }
        set {
            typeProperty = newValue
        }
    }
}

AClass.typeProperty = 1234

let classInstance: AClass = AClass()
classInstance.instanceProperty = 100

print(AClass.typeProperty) //110
print(AClass.typeComputedProperty) //110

 

 

읽어주셔서 감사합니다🤟

 

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.