접근제어란?
- 객체지향 프로그래밍 패러다임에서 은닉화를 구현하기 위한 핵심 기능이다.
- 접근제어란 코드끼리 상호작용시 파일 간 또는 모듈 간에 접근을 제한할 수 있는 기능이다.
- 접근제어를 통해 코드의 상세 구현은 숨기고 허용된 기능만 사용하는 인터페이스를 제공할 수 있다.
모듈과 소스파일
모듈(module)
- 배포할 코드의 묶음 단위이다.
- 하나의 프레임워크나 라이브러리 또는 애플리케이션이 모듈 단위가 될 수 있음.
- 스위프트에서는 import 키워드를 사용해 불러온다.
소스파일
- 하나의 스위프트 소스코드 파일을 의미.
- 보통 다른 프로그래밍 언어에서는 통상 파일 하나에 타입을 하나만 정의하지만 스위프트에서는 파일 하나에 여러 타입을 정의가능하다.
접근수준
- 접근제어는 접근수준(Access Level) 키워드를 통해 구현가능하다.
- 각 타입(클래스, 구조체, 열거형 등)에 특정 접근수준을 지정할 수 있고, 타입 내부의 프로퍼티, 메서드, 이니셜라이저, 서브스크립트 각각에도 접근수준을 지정할 수 있다.
- open, public, internal, fileprivate, private 5가지가 있다.
개방 접근수준 - open
- 공개 접근수준 이상으로 높은 수준이며, 클래스와 클래스의 멤버에서만 사용할 수 있다.
- 클래스를 개방 접근수준으로 명시하는 것은 그 클래스를 다른 모듈에서도 부모클래스로 사용하겠다는 목적으로 클래스를 설계하고 코드를 작성했음을 의미한다.
공개 접근수준 - public
- 어디서든 쓰일 수 있다.
- 자신이 구현된 소스 파일은 물론, 그 소스파일이 속해 있는 모듈, 그 모듈을 가져다 쓰는 모듈 등 모든 곳에서 사용 할 수 있다.
- 공개 접근수준은 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 사용된다.
- 스위프트의 기본 요소는 모두 공개 수준으로 구현되어 있다고 볼 수 있다.
- 개방 접근수준 VS 공개 접근수준 차이점
- 개방 접근수준을 제외한 다른 모든 접근수준의 클래스는 그 클래스가 정의된 모듈 안에서만 상속할 수 있다.
- 개방 접근수준을 제외한 다른 모든 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 안에서만 재정의할 수 있다.
- 개방 접근수준의 클래스는 그 클래스가 정의된 모듈 밖의 다른 모듈에서도 상속할 수 있다.
- 개방 접근수준의 클래스 멤버는 해당 멤버가 정의된 모듈 밖의 다른 모듈에서도 재정의할 수 있다.
내부 접근수준 - Internal
- 내부 접근수준은 기본적으로 모든 요소에 암무적으로 지정하는 기본 접근수준이다.
- 소스파일이 속해 있는 모듈 어디에서든 쓰일 수 있다.
- 다만 그 모듈을 가져다 쓰는 외부 모듈에서는 접근할 수 없다.
- 보통 외부에서 사용할 클래스나 구조체가 아니며, 모듈 내부에서 광역적으로 사용할 경우 내부 접근 수준을 지정한다.
파일외부비공개 접근수준 - fileprivate
- fileprivate으로 지정된 요소는 그 요소가 구현된 소스파일 내부에서만 사용할 수 있다.
- 해당 소스파일 외부에서 값이 변경되거나 함수를 호출하면 부작용이 생길 수 있는 경우에 사용하면 좋다.
비공개 접근수준 - private
- 가장 한정적인 범위이다.
- 비공개 접근수준으로 지정된 요소는 그 기능을 정의하고 구현한 범위 내에서만 사용할 수 있다.
- 비공개 접근수준으로 지정한 기능은 심지어 같은 소스파일 안에 구현한 다른 타입이나 기능에서도 사용할 수 없다.
fileprivate VS private
- fileprivate 접근수준으로 지정한 요소는 같은 파일 어떤 코드에서도 접근 가능하다.
- A.swift 소스파일 내부에 A Class, B Class, C Struct가 있고, C Class에 fileprivate 접근수준의 a 프로퍼티가 있다면 B Class, C Struct에서 모두 a 프로퍼티에 접근 가능하다.
- private 접근수준으로 지정한 요소는 같은 파일 내부에 다른 타입의 코드가 있더라도 접근이 불가하다.
- 하지만 extension 코드가 같은 파일에 존재하는 경우에는 접근가능하다.
접근제어 구현 참고사항
💡 모든 타입에 적용되는 접근수준의 규칙은 '상위 요소보다 하위 요소가 더 높은 접근수준을 가질 수 없다.'
- 비공개 접근수준으로 정의한 구조체 내부의 프로퍼티로 내부수준이나 공개수준을 갖는 프로퍼티를 정의할 수 없다.
- 또한 함수의 매개변수로 특정 접근수준이 부여된 타입이 전달되거나 반환된다면, 그 타입의 접근수준보다 함수의 접근수준이 높게 설정될 수 없다.
- 함수뿐만 아니라 튜플의 내부 요소 타입 또한 튜플의 접근수준보다 같거나 높아야 한다.
읽기 전용 구현
- 구조체 또는 클래스를 사용하여 저장 프로퍼티 구현시 허용된 접근수준에서 프로퍼티 값을 가져갈 수 있다.
- 그런데 값을 변경할 수 없도록 구현하고 싶다면 어떻게 해야 할까?
-
설정자(setter)만 낮은 접근수준을 갖도록 제한할 수 있다.
-
요소의 접근수준 키워드 뒤에 접근수준(set)
처럼 표현하면 설정자의 접근수준만 더 낮도록 지정해줄 수 있다.
public private(set) var publicGetOnlyStoredProperty: Int = 0