study record

[Swift] 스위프트 프로그래밍 - 접근제어 본문

Swift/스위프트 프로그래밍

[Swift] 스위프트 프로그래밍 - 접근제어

asong 2021. 11. 30. 22:00

접근제어

접근제어는 코드끼리 상호작용을 할 때 파일 간, 모듈 간에 접근을 제한할 수 있는 기능이다. 접근제어를 통해 코드의 상세 구현은 숨기고, 허용된 기능만 사용하는 인터페이스를 제공할 수 있다.

 

접근제어의 필요성

객체지향 프로그래밍 패러다임에서 캡슐화, 은닉화를 구현하는 이유는 외부에서 보거나 접근하면 안 되는 코드가 있기 때문이다. 불필요한 접근으로 의도치 않은 결과를 초래하거나 꼭 필요한 부분만 제공해야 하는데 전체 코드가 노출될 가능성이 있을 때 접근제어를 이용한다.

 

모듈과 소스파일

스위프트의 접근제어는 모듈과 소스파일을 기반으로 설계되었다.

모듈은 배포할 코드의 묶음 단위이다. 하나의 프레임워크나 라이브러리, 애플리케이션이 모듈 단위가 될 수 있다. import 키워드를 통해 불러온다.

소스파일은 하나의 스위프트 소스 코드 파일을 의미한다. 보통 파일 하나에 타입 하나만 정의하지만, 때로는 소스파일 하나에 여러 타입(여러 클래스나, 구조체 등)을 정의하거나 구현할 수도 있다.

 

접근 수준

접근제어는 접근 수준 키워드를 통해 구현할 수 있다. 각 타입에 특정 접근수준을 지정할 수 있고, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도 접근수준을 지정할 수 있다.

접근수준을 명시할 수 있는 키워드는 open, public, internal, fileprivate, private 다섯 가지가 있다.

스위프트의 접근 수준은 기본적으로 모듈과 소스파일에 따라 구분한다.

  • 개방 접근수준 - open : 모듈 외부까지 (클래스에서만 사용 가능)
  • 공개 접근수준 - public : 모듈 외부까지
  • 내부 접근수준 - Internal : 모듈 내부
  • 파일외부비공개 접근수준 - fileprivate : 파일 내부
  • 비공개 접근수준 - private : 기능 정의 내부

 

공개 접근수준 - public

public은 어디서든 쓰일 수 있다. 공개 접근수준은 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 쓰인다. 우리가 사용하는 스위프트의 기본 요소는 모두 공개 접근수준으로 구현되어 있다고 생각하면 된다.

 

개방 접근수준 - open

개방 접근수준은 공개 접근수준 이상으로 높은 접근수준이다. 클래스와 클래스의 멤버에서만 사용할 수 있다.

클래스를 개방 접근 수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 부모클래스로 사용하겠다는 목적으로 클래스를 설계하고 코드를 작성했음을 의미한다.

 

내부 접근수준 - internal

내부 접근수준은 기본적으로 모든 요소에 암묵적으로 지정하는 기본 접근수준이다. 소스파일이 속해있는 모듈 어디에서든 쓰일 수 있다. 다만 그 모듈을 가져다 쓰는 외부 모듈에서는 접근할 수 없다. 보통 외부에서 사용할 클래스나 구조체가 아니며, 모듈 내부에서 광역적으로 사용할 경우 내부 접근수준을 지정한다.

 

파일외부비공개 접근수준 - fileprivate

파일외부비공개 접근수준으로 지정된 요소는 그 요소가 구현된 소스파일 내부에서만 사용할 수 있다. 해당 소스파일 외부에서 값이 변경되거나 함수를 호출하면 부작용이 생길 수 있는 경우에 사용하면 좋다.

 

비공개 접근수준 - private

비공개 접근수준은 가장 한정적인 범위이다. 기능을 정의하고 구현한 범위 내에서만 사용할 수 있다.

 

접근제어 구현 참고사항

  • 상위 요소보다 하위요소가 더 높은 접근수준을 가질 수 없다.
  • 함수의 매개변수로 특정 접근수준이 부여된 타입이 전달되거나 반환된다면, 그 타입의 접근수준보다 함수의 접근수준이 높게 설정될 수 없다.
  • 열거형의 접근수준을 구현할 때 열거형 내부의 각 case별로 따로 접근수준을 부여할 수는 없다. 각 case의 접근수준은 열거형 자체의 접근수준을 따른다. 또한 열거형의 원시 값 타입으로 열거형의 접근수준보다 낮은 접근수준의 타입이 올 수는 없다.
private class AClass {
	//공개 접근수준을 부여해도 AClass의 접근수준이 비공개 접근수준이므로
	// 이 메서드의 접근수준도 비공개 접근수준으로 취급된다.
	public func someMethod(){
}}

//AClass의 접근수준이 비공개 접근수준이므로
// 공개 접근수준 함수의 매개변수나 반환 값 타입으로 사용할 수 없다.
public func someFunction(a: AClass) -> AClass {
//오류발생
  return a
}

 

fileprivate과 private

fileprivate 접근수준으로 지정하면 같은 파일 어떤 코드에서도 접근할 수 있다.

private 접근수준으로 지정한 요소는 같은 파일 내부에 다른 타입의 코드가 있더라도 접근이 불가능하다. 그러나 자신을 확장하는 익스텐션 코드가 같은 파일에 존재하는 경우에는 접근할 수 있다.