Swift. 접근 제어자

Choooose·2023년 2월 7일
0

Swift

목록 보기
1/5
post-thumbnail

접근 제어란 ?


접근 제어란 코드 간의 접근을 소스파일이나 모듈 단위 등으로 제한하는 것을 의미한다.
이렇게 코드 접근을 제한하여 특정 코드의 세부적인 부분을 감추거나 필요한 부분만을 사용할 수 있도록 제어할 수 있다.

접근 레벨


접근 제어를 구현할 수 있도록 해주는 것이 접근 레벨이다.

Swift에서는 5개의 접근 레벨을 제공한다.
개방적 → open → public → internal → file private → private출처 : https://samwize.com/2017/04/20/access-levels-in-swift/

open

open은 코드를 선언한 모듈이 아닌 다른 모듈에서까지 사용이 가능하다.
또한 다른 모듈에서 subclassing과 override 까지 가능하다.

public

publicopen과 동일하게 다른 모듈에서 사용이 가능하다.
그러나 open과의 차이점은 다른 모듈에서는 subclassing과 override가 불가능하다.

internal

우리가 기본적으로 코드를 작성하면서 접근 제어자를 명시해주지 않으면 Internal 로 선언된다.
Internal은 해당 모듈 전체에서 사용이 가능한 접근제어자이다.

file private

작성된 ( 선언된 ) 소스파일 안에서만 사용이 가능하다.
.swift 파일 하나에서만 사용할 수 있는 코드라고 보면 될 것 같다.

private

가장 제한이 큰 접근제어자이다.
특정 기능, 구현부에서만 사용할 수 있도록하는 제어자로 같은 소스파일이어도 다른 기능 또는 다른 타입으로 구현된 코드의 경우에는 접근이 불가능하다.

라이브러리 혹은 프레임워크를 import 하여 사용할 때 API를 뜯어보면 사용이 가능한 부분이 있고 불가능한 부분이 있을텐데 이때 사용 가능한 부분이 public 또는 open으로 선언되어 있고 사용 가능하면서 override까지 가능한 부분은 open으로 선언되어 있다고 봐도 될 것 같다

Custom Type 접근 제어자


커스텀 클래스에 특정 레벨을 지정할 수 있다.

예를 들어

private class PrivateClass {
	func privateMethod() {
		...
	}
}

의 경우 이때는 class가 private 으로 선언되었기 때문에 privateMethod() 함수도 클래스 구현부의 외부에서는 사용할 수 없는 것을 확인할 수 있다.
file-private, internal 도 동일하다
그렇다면 public 또는 open 이라면 ?
신기하게도 publicopen에서는 내부 멤버까지 class를 따라가지는 않고 모두 internal로 선언이된다.
이유는 public API를 만드는 과정에서 실수로 노출되지 말아야할 API를 노출시킬 위험이 있기 때문이다.
따라서 public 또는 open을 갖는 커스텀 클래스를 작성한다면

public class publicClass {
	public func publicMethod() {
		...
	}
}

위와 같이 내부 멤버에도 public으로 접근 제어를 명시해야한다.

Tuple Type의 접근 제어자

Tuple은 접근제어자를 명시적으로 표시하지 않는다.
Tuple의 접근 레벨은 해당 Tuple에 사용된 타입 중 가장 제한적인 타입을 따라가게된다.
왜냐하면 Tuple의 접근 레벨은 Tuple이 사용될때 자동으로 추론되기 때문이다.

Function Type의 접근 제어자

함수의 접근제어자는 함수의 매개변수 또는 리턴타입에서의 가장 제한적인 접근 레벨로 지정된다.

예를 들어

func someFunc() -> privateClass {
	...
}

이라는 함수가 있고 이때의 리턴 타입이 private인 class일때는 함수 또한 private으로 접근 레벨이 지정된다.

그러나 이때 함수의 기본 접근 제어자가 리턴 타입의 접근 제어자와 일치 하지 않다면 오류가 발생하게 되는데,
이때는 리턴타입과 동일한 private으로 명시를 해주어야한다.

리턴타입이 private 일때는 fileprivate, private 모두 상관없는 것 같다..?

정리하면 함수의 리턴 타입 또는 매개변수의 가장 제한적인 접근 레벨에 따라서 함수 또한 접근 레벨이 지정되고 이때 기본 접근 레벨과 일치하지 않는 다면 함수또한 명시적으로 접근제어자를 지정해주어야한다.

Enumeration Type의 접근 제어자

Enum의 개별 case는 자동적으로 Enum의 접근제어자와 동일한 접근 레벨로 지정된다.

또한 Raw values 또는 Associated values는 Enum 보다 개방적인 접근 레벨로 명시하여 지정할 수 있다.

Subclassing의 경우 접근 제어자

Subclass는 Superclass 보다 개방적인 접근 레벨로 지정될 수 없다.

Subclass는 Superclass의 멤버에 접근할 수 있는데 이때 Subclass가 접근 레벨이 더 개방적이라면 Superclass의 멤버에 접근하지 못할 수 있기 때문이다.

상수, 변수, 프로퍼티 접근 제어자

상수, 변수, 프로퍼티의 경우에는 해당 타입보다 더 개방적인 접근제어자를 가질 수 없다.

위와 같이 instance는 internal class는 private으로 선언되는 경우 instance가 더욱 개방적인 접근제어자를 가짐으로 인해 오류가 발생한다.

Initializer의 접근 제어자

사용자가 정의하는 이니셜라이저의 경우에는 더 제한적인 접근 레벨을 명시하여 지정할 수 있다.
그러나 required initializer는 속한 class와 동일한 접근 레벨이어야 한다.

Protocol의 접근 제어자

protocol의 접근 레벨을 명시하기 위해서는 선언하는 시점에 명시해야하며 protocol 내부 또한 동일한 접근 레벨을 갖는다.

Extension의 접근 제어자

extension의 접근 레벨은 원래 타입과 동일한 접근 레벨을 갖는다.
이때 extension 의 접근 제어자를 private 과 같이 명시해주는 경우에는 extension 내부 또한 private으로 접근 레벨이 지정된다.

Generic의 접근 제어자

generic 타입의 함수 또는 타입 그 자체는 타입 매개변수, 타입 중 가장 제한적인 접근 레벨을 갖는다.

참고


https://jusung.gitbook.io/the-swift-language-guide/language-guide/25-access-control

https://zeddios.tistory.com/389

https://velog.io/@zooneon/Swift-접근제어에-대해-알아보자

0개의 댓글