본문 바로가기

카테고리 없음

[Swift]I'm on the Access Level !~(접근수준)

I’m on the Access,, Level~ 제껴라 제껴라 제껴라~

근데 제끼면안됨 아주아주 중요하거덩 바로 알아보자

 

Access Level ( 접근수준 )

접근 수준이 존재하는 이유 : 변수 메서드 타입 등을 외,내 부 모듈에서도 접근하여 사용하기 위함

 

접근 수준을 이해하려면 모듈과 소스파일을 이해해야한다

 

이론상으로 

모듈은 코드를 배포하는 단일 단위로 프레임워크, 어플리케이션, 라이브러리 등이라고 부르고

소스파일은 모듈안에서 생성되는 file을 의미한다.

쉽게 이해하기위해서 xcode를 만들어 Project를 생성하여 그안에 소스파일등을 만들어 그안에 코딩을 할것이다

이때 Project파일을 모듈이라하고 file이 소스파일이다

 

참고로 다른 모듈에서 내가만든 모듈을 사용하고자할땐 import라는 기능을 사용한다.

 

자세한 범위 접근은 아래서 설명하겠다.

 

 

종류는 5가지가 있다

 

키워드 접근수준 범위

 

open              =      개방         =        모듈 외부까지(다른프로젝트까지)

public            =      공개         =        모듈 외부까지(다른프로젝트까지)

internal         =      내부          =        모듈 내부(해당프로젝트)

file-private   =     파일내부    =        파일 내부(소스파일내에서까지)

private          =     비공개       =        기능정의 내부(타입?이나 메서드내에서만)

 

#기본 접근레벨 (Default Access Levels)

Internal은 아무것도 명시안하면 가지게되는 default값이다.

 

!주의사항!

public&open < internal < file-private < private 의 공개범위 순서도인데

당연히 intetnal안에서 public을 사용할 수 없다.

 

이중에서 개방접근수준이 공통분모 외 사항이있어 정리하고 넘어가면 좋을듯 하다

 

#개방 접근수준 – open(클래스와 클래스의 멤버에서만 사용가능)

open 키워드로 지정할 수 있는 개방(Open) 접근수준은 공개(Public) 접근수준 이상으로 높은 접근수준이며 open은 클래스에만 해당사항이다.

 

 

#프레임워크를 위한 접근레벨 (Access Levels for Frameworks)

public혹은 open으로 지정해서 다른 모듈에서 볼 수 있고 접근 가능하도록 만들어야함

#만약 프레임워크내에서 구체적으로 감추고싶은 내용이있으면 그 부분은 internal을 사용하면됩니다.

오픈하고자하는 부분만 public or open으로 지정해보자

 

#커스텀 타입 (Custom Types)

커스텀 클래스에 특정 접근레벨을 지정할 수 있습니다. 그 레벨을 지정하면 그 클래스 안의 프로퍼티와 리턴 타입의 접근레벨은 클래스 레벨의 접근 권한만 사용할 수 있다 예를 들어, 클래스를 file-private 클래스로 선언하면 그안의 프로퍼티와 함수 파라미터 그리고 반환 타입도 file-private 접근 권한을 갖습니다. 다시말해 특정 타입의 접근레벨의 지정은 그 타입의 멤버(프로퍼티, 메소드 초기자 와 서브스크립트)에 기본 접근레벨에 영향을 미칩니다.

단, public타입은 예외

[매우중요]

IMPORTANT public타입은 기본 적으로 internal 멤버를 갖고 public을 갖지 않습니다. 이렇게 동작하는 이유는 public API를 만들시 노출되지 말아야 할 API가 실수로 노출되는 것을 막기 위함입니다. 그래서 노출시키고 싶은 멤버는 명시적으로 public 접근제어자를 붙여줘야 합니다.

 

#함수타입 (Function Types)

함수 타입의 접근레벨은 함수의 파라미터 타입과 리턴타입의 접근레벨 중 최소의 접근레벨로 계산돼 사용됩니다. 그래서 그것에 맞는 접근 레벨을 함수 앞에 명시해 줘야 합니다.

 

Ex) internal type private type
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here

}

 

이 함수를 적절히 선언하기 위해서는 아래와 같이 함수 앞에 private접근레벨을 지정해 줘야 합니다.

 

private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
    // function implementation goes here

}

 

#열거형 타입 (Enumeration Types)

열거형은 enum앞에 명시된 접근수준을 따릅니다.( case별로 접근수준 설정 불가능)

 

#고유값과 연관값(Raw Values and Associated Values)

 

고유값과 연관값을 사용하는 타입의 경우 반드시 그 타입보다 높은 접근 레벨을 가져야 합니다. 즉, internal접근 레벨을 갖고 있는 열거형 타입에서 private접근레벨을 갖는 고유값을 사용할 수 없습니다.

 

위에서 설명한 !주의사항!과 같은 내용이며 상속에도 포함이 되는 내용입니다.

 

#서브클래싱 (Subclassing)

 

클래스타입에서 높은 접근수준인 A클래스를 상속받은 B는 일반적으로 더 낮은 접근수준을 갖게된다.

 

Ex) 



public class A {
	fileprivate func someMethod() {}
}



internal class B: A {
	override internal func someMethod() {}
}

 

하지만 메서드를 그렇지않다.

위처럼 상속받은 클래스내 메서드를 재정의할때 더 높은 범위로 지정하여 사용할 수 있다는 것이다. 

 

[가능한이유] -> 이해가 잘안됨….ㅠㅠ super호출이되는것과 무슨상관이있는거지….?

이게 가능한 이유는 class A와 class B가 같은 소스파일에 선언돼 있어서 class B의 someMethod구현에서 super.someMethod()를 호출하는 것이 유효하기 때문입니다.

 

(프로토콜과 익스텐션은 아직 공부가 더 필요..)