Swift + iOS/Swift

[Swift] 접근제어 Access Control

군옥수수수 2018. 1. 21. 22:03

[Swift] 접근제어 Access Control


안녕하세요. 오늘은 접근제어에 대해 공부를 해보았습니다. 접근제어는 객체지향 패러다임에서 중요한 개념 중 하나인 은닉화를 구현하기 위한 아주 중요한 기능입니다. 그럼 바로 공부한 내용을 정리해보도록 하겠습니다.

Module

우선 접근제어를 이해하려면 스위프트에서의 모듈의 개념을 이해하셔야 합니다. 모듈은 코드의 묶음 단위로 프레임워크, 라이브러리, 어플리케이션처럼 배포할 코드들의 묶음을 나타냅니다. 즉 하나의 프레임워크는 하나의 모듈이고 우리가 Xcode로 만드는 프로젝트 역시 하나의 모듈입니다. 그리고 우리는 import를 통해 외부 모듈을 우리의 프로젝트(모듈)에서 사용할 수 있습니다.


Access Level

본격적으로 접근수준의 종류에 대해 알아보도록 하겠습니다. 간단히 정리하면 다음과 같습니다.

접근수준키워드범위
개방 접근수준open모듈 외부에서도 접근 가능
공개 접근수준public모듈 외부에서도 접근 가능
내부 접근수준internal하나의 모듈 내부에서만 접근 가능
파일내부 접근수준fileprivate하나의 파일 내에서만 접근 가능
비공개 접근수준private정의한 블록 내부에서만 접근 가능

그럼 이제 하나하나 살펴보도록 하겠습니다.

1. open

open은 정의된 모듈외에서도 접근이 가능합니다. 하지만 위의 표를 보면 public과 다를게 없어 보이는데요. 이 둘에는 다음과 같은 차이점이 존재합니다.

  1. 모든 접근수준 중 open만이 모듈 밖의 다른 모듈에서 상속될 수 있습니다. (클래스)
  2. 모든 접근수준 중 open으로 선언된 클래스의 멤버(프로퍼티, 메소드)들만이 다른 모듈에서 override될 수 있습니다.

예를 들어보도록 하겠습니다. iOS 프로젝트를 할 때 우리는 반드시 UIKit을 사용하게 됩니다. UIKit은 애플의 개발자들이 만들어 놓은 하나의 외부 모듈로 우리가 어플리케이션을 만들 때 우리의 프로젝트(모듈)에서 필수로 사용하는 외부모듈 중 하나입니다.


그리고 그 중 가장 우리에게 익숙한 UIViewController 클래스를 살펴보도록 하겠습니다. cmd를 누른채 UIViewController를 클릭하시면 "Jump to Definition"이라는 버튼이 보이고 해당 버튼을 클릭하면 UIViewController의 클래스의 접근수준과 그 멤버들의 접근수준을 확인할 있습니다.

보시다시피 UIViewControlleropen으로 선언되어 있습니다. 그렇기 때문에 우리는 우리의 프로젝트에서 UIViewController를 상속받는 여러 뷰 컨트롤러를 생성할 수 있습니다.

또한 UIViewControlleropen으로 선언되어 있기 때문에 이를 상속받는 클래스에서 public으로 선언된 메소드들도 override할 수 있습니다.

2.public

public으로 선언된 요소들 역시 모듈 바깥에서도 접근이 가능합니다. 하지만 클래스를 public으로 선언한다면 바깥에서 생성은 할 수 있으나 해당 클래스를 상속할 수도 해당 클래스의 멤버들을 override할 수도 없습니다. 즉 만일 UIViewControllerpublic으로 선언되어 있다면 아무리 import를 해서 우리의 프로젝트로 가져와도 해당 클래스를 상속받는 클래스는 만들 수 없습니다.

물론 public으로 선언되어 있다면 멤버는 open으로 선언될 수 없습니다. 이는 밑에서 더욱 자세히 다루도록 하겠습니다.

3.internal

internal은 따로 접근제어를 선언해주지 않으면 기본으로 할당되는 default 접근제어 수준입니다. internal은 같은 모듈 내에서는 어디서든 접근이 가능하고 클래스의 경우는 어느 곳에서도 해당 클래스를 상속받을 수 있습니다.

4.fileprivate

fileprivate는 하나의 스위프트 파일(.swift) 내부에서만 접근이 가능한 접근제어 수준입니다. 다른 언어에서는 하나의 파일에 하나의 클래스 혹은 하나의 타입만 정의하지만 스위프트에서는 종종 해당 타입과만 관련된 요소면 같은 파일 내에서 여러 타입을 정의하곤 합니다.

즉 하나의 타입에만 종속되어 사용되는 혹은 사용되어지는 타입은 같은 파일 내에 정의하고 접근제어를 fileprivate으로 선언하면 그 파일(.swift) 내부에서만 해당 타입에 접근이 가능합니다.

5.private

아마 여러분에게 가장 익숙하고 그리고 그 익숙한 개념과 가장 일치하는 스위프트의 접근제어 수준일 것입니다. private은 그 요소가 선언된 영역(블록)내에서만 접근이 가능합니다.


접근제어간의 충돌

위에서 언급한 "물론 public으로 선언되어 있다면 멤버는 open으로 선언될 수 없습니다." 라는 문장에 대해 알아보도록 하겠습니다. 어찌보면 당연한 개념일 수 있습니다.

  1. 바깥 요소의 접근제어 수준보다 높은 수준의 내부 요소는 있을 수 없다.
  2. 특정 접근제어 수준의 타입이 함수의 매개변수나 반환되는 타입일 경우 함수는 해당 값의 접근제어보다 높을 수 없다.

예를 들어 설명해드리면 더 쉽게 이해가 되실 겁니다.

먼저 첫번째의 경우 클래스의 접근수준이 private이면 클래스의 멤버들은 public, internalprivate보다 상위 수준의 접근수준이 될 수 없고 선언이 되어도 private으로 취급됩니다.

두번째의 경우 메소드나 함수가 public한데 private한 매개변수를 받거나 private한 값을 반환하는 것은 상식적으로 맞지 않습니다. 이때 매개변수의 타입이나 반환되는 값의 접근제어 수준은 메소드나 함수의 접근제어 수준과 같거나 높아야 합니다.


마무리

오늘은 이렇게 스위프트의 접근제어에 대해 알아보았습니다. 처음에는 이전에 공부했던 자바의 접근제어를 선언하는 키워드가 달라 헷갈렸으나 오히려 자바보다 접근수준에 대해 직관적인 이름으로 보다 쉽게 이해할 수 있었습니다. 앞으로 프로젝트를 진행할 때 보다 접근제어에 신경을 쓰며 코드를 작성할 수 있을 것 같습니다. 감사합니다.