3월 11일 TIL (접근제한자)

이승원·2024년 3월 11일
0

TIL

목록 보기
34/75
post-thumbnail

접근 제한자

  • 코드 요소에 대한 외부 접근을 제한하여 모듈간의 접근성과 보안을 조절하는 것.
  • 접근 제한자를 알기 위해서는 모듈과 소스파일의 차이를 알아야한다.
  • 모듈 (Module)
    - 배포할 코드의 묶음 단위
    • 하나의 프레임워크, 라이브러리, 어플리케이션이 모듈 단위가 될 수 있다.
    • import 키워드를 통해 불러올 수 있다.
    • 흔히 쓰는 import Foundation 같은 경우에도 Foundation 모듈을 불러오는 것이다.
  • 소스파일
    - 하나의 swift 소스 코드 파일을 의미한다.
  • 아래는 제약이 적은 순서부터 많은 순서대로 정리하였다.

Open

  • 모든 소스 파일에서 해당 level 접근 가능 + 모든 곳에서 서브클래싱 가능
  • 클래스와 클래스 멤버에서만 사용할 수 있고, 다른 모듈에서 서브클래싱이 가능하다.
  • open 을 사용하느것은 해당 클래스를 다른 모듈에서도 슈퍼클래스로 사용하겠다는 의미로 해당 클래스를 설계하고 만들었다는 것을 의미한다.
// open 
open class Vehicle {
    open func startEngine() {
        print("Engine started")
    }
}

open class Car: Vehicle {
    open var carType: String = "Sedan"
}

Public

  • 모든 소스 파일에서 해당 level 접근 가능 + 같은 모듈 내에서만 서브 클래싱 가능
  • 주로 프레임워크에서 외부와 연결될 인터페이스를 구현하는데 많이 사용함.
// public 
public struct Point {
    public var x: Int
    public var y: Int

    public init(x: Int, y: Int) {
        self.x = x
        self.y = y
    }

    public mutating func moveByX(_ deltaX: Int, y deltaY: Int) {
        self.x += deltaX
        self.y += deltaY
    }
}

Internal (Default)

  • 같은 모듈 내에서만 접근가능
  • 소스파일이 속해있는 모듈 어디에든 접근 할 수 있지만 외부 모듈에서는 접근할 수 없다.
// internal
// 굳이 internal 명시를 안해도 default로 Internal 로 인식. 
internal class InternalClass {
    internal var internalProperty: Int = 10

    internal func doSomethingInternally() {
        print("Internal operation performed")
    }
}

internal let internalConstant = 20

FilePrivate

  • 같은 소스파일 내에서만 접근 가능
  • 서로 다른 클래스가 같은 하나의 소스파일에 정의되어있고, fileprivat로 선언되어 있다면, 두 클래스는 서로 접근할 수 있다.
// fileprivate
class OuterClass {
    fileprivate var outerVariable = 30

    fileprivate func outerFunction() {
        print("Outer function called")
    }

    fileprivate class InnerClass {
        fileprivate func innerFunction() {
            print("Inner function called")
        }
    }
}

Private

  • 클래스 내부에서만 접근 가능
  • filePrivate과 달리 같은 파일안에 있어도 서로 다른 클래스이고 private로 선언되어 있다면 두 요소는 접근할 수 없다.
  • 두 클래스가 상속관계여도 접근할 수 없다.
  • 클래스안에 private요소들은 인스턴스를 생성해도 접근이 불가능하다.
  • 쉽게 get,set 메서드로 요소들을 안전하게 사용하는 방법이라고 생각하면 된다.
// private
class MyClass {
    private var privateVariable = 40

    private func privateFunction() {
        print("Private function called")
    }
}

상위 요소 보다 하위 요소가 더 놓은 접근 수준을 가질 수 없다.

private struct Car {
	public var model: String // 오류
}
// Public 이 Private 보다 더 높은 접근 수준을 갖고 있으나,
// Public 이 Private로 선언된 클래스 내부에 있기 때문에 오류. 

Mutating

  • Mutating 키워드는 구조체 (Struct) 나 열거형 (Enum) 내에서 메서드 (Method)가 해당 구조체 또는 열거형의 속성을 수정할 수 있도록 하는 키워드다.
  • 클래스 (Class)에서 사용하지 않는 이유는, 구조체나 열거형은 값 타입이고, 클래스는 참조 타입이기 때문이다.
  • 값 타입은 데이터를 복사하여 전달하는 방식이고, 참조 타입은 메모리 주소를 전달하는 방식이다.
// 구조체 예시
struct Point {
    var x = 0.0, y = 0.0

    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

var point = Point(x: 1.0, y: 1.0)
print("Before moving: x = \(point.x), y = \(point.y)")

point.moveBy(x: 2.0, y: 3.0)
print("After moving: x = \(point.x), y = \(point.y)")

// Before moving: x = 1.0, y = 1.0
// After moving: x = 3.0, y = 4.0


// 열거형 예시
enum TrafficLight {
    case red, yellow, green

    mutating func next() {
        switch self {
        case .red:
            self = .green
        case .yellow:
            self = .red
        case .green:
            self = .yellow
        }
    }
}

var currentLight = TrafficLight.red
print("Current light is \(currentLight)")

currentLight.next()
print("Next light is \(currentLight)")
profile
개발자 (진)

0개의 댓글