
add(x:y:)
add(first:second:)
add(_:_:)
add(_:with:)
각 함수의 시그니처(함수명과 자료형)는 다음과 같습니다.
swift
func add(x: Int, y: Int) -> Int
- 외부 매개변수명: x, y
- 내부 매개변수명: x, y
- 반환형: Int
swift
func add(first x: Int, second y: Int) -> Int
- 외부 매개변수명: first, second
- 내부 매개변수명: x, y
- 반환형: Int
swift
func add(_ x: Int, _ y: Int) -> Int
- 외부 매개변수명 생략 (언더바 _로 표시)
- 내부 매개변수명: x, y
- 반환형: Int
swift
func add(_ x: Int, with y: Int) -> Int
- 첫 번째 매개변수 외부 매개변수명 생략(_)
- 두 번째 매개변수 외부 매개변수명: with
- 내부 매개변수명: x, y
- 반환형: Int
정리하면, 모든 함수 이름은 add이고 모두 Int 타입 파라미터 두 개를 받아서 Int 타입을 반환합니다.

numberOfRowsInSection
func tableView(
_ tableView: UITableView,
numberOfRowsInSection section: Int
) -> Int
이 함수의 함수명과 자료형
✅ 함수명
- tableView(_:numberOfRowsInSection:)
👉 Swift에서는 **외부 매개변수명(argument label)**까지 포함해서 함수명을 구성합니다.
✅ 함수의 자료형 (타입)
✅ 의미 풀이
- 입력:
- UITableView (첫 번째 파라미터, _라서 호출 시 이름 생략)
- Int (section)
- 출력:
- Int (해당 섹션의 row 개수)
🔍 추가 설명
이 함수는 UIKit의
UITableViewDataSource 프로토콜에 포함된 메서드입니다.
즉, 테이블뷰가 "이 섹션에 몇 개의 셀이 있냐?"라고 물을 때 호출되는 함수입니다.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return cell }
✅ 함수명
- tableView(_:cellForRowAt:)
👉 외부 매개변수명까지 포함된 완전한 함수 시그니처 이름입니다.
✅ 함수의 자료형 (타입)
✅ 의미 풀이
- 입력:
- UITableView (어떤 테이블뷰인지)
- IndexPath (몇 번째 섹션/행인지)
- 출력:
- UITableViewCell (해당 위치에 표시할 셀)
🔍 추가 설명
이 함수 역시
UIKit의
UITableViewDataSource에 포함된 필수 메서드입니다.

디폴드 매개변수(argument)
->
**디폴트 매개변수(Default Parameter)**는
함수를 호출할 때 값을 생략하면 자동으로 기본값이 사용되는 매개변수를 의미합니다.
✅ 개념 이해
함수를 만들 때 미리 값을 지정해두면:
- 호출 시 값을 넘기면 → 그 값 사용
- 호출 시 생략하면 → 기본값(default) 사용
✅ Swift 예시
print("Hello, \(name)!")
}
호출 방법
greet() // Hello, Guest!
👉 name을 안 넘기면 "Guest"가 자동으로 들어갑니다.
✅ 매개변수가 여러 개인 경우
return Int(pow(Double(base), Double(exponent)))
}
power(base: 3) // 9 (exponent 기본값 2 사용)
✅ 왜 사용할까?
- 함수 호출을 더 간단하게 만들기 위해
- 자주 쓰는 값을 기본값으로 설정하기 위해
- API를 더 유연하게 만들기 위해
✅ 한 줄 정리
👉 디폴트 매개변수 = 값을 안 넣으면 자동으로 대신 들어가는 미리 정해둔 값
print문
func print( _ items: Any..., separator: String = " ", terminator: String = "\n" )
String | Apple Developer Documentation
A Unicode string value that is a collection of characters.
developer.apple.com
1️⃣ 함수명
👉 실제로는 다음과 같은 시그니처 이름을 가집니다:
2️⃣ 첫 번째 매개변수: 가변 매개변수 + 외부 이름 생략
✔ 의미
- _ : 외부 매개변수명 생략 (호출할 때 이름 안 씀)
- items : 내부에서 사용할 이름
- Any : 어떤 타입이든 받을 수 있음
- ... : 가변 매개변수 (Variadic Parameter)
✔ 결과
👉 여러 개의 값을 한 번에 받을 수 있음
👉 내부적으로는:
3️⃣ 두 번째 매개변수: 기본값 있는 매개변수
✔ 의미
- 출력 값들 사이에 넣을 문자열
- 기본값: " " (공백)
✔ 사용 예
print("A", "B", "C", separator: "-") // A-B-C
4️⃣ 세 번째 매개변수: 기본값 있는 매개변수
✔ 의미
- 출력 끝에 붙는 문자열
- 기본값: 줄바꿈 (\n)
✔ 사용 예
print("Hello", terminator: "") // Hello (줄바꿈 없음)
5️⃣ 함수의 리턴 타입
👉 생략되어 있음 → Void (아무것도 반환하지 않음)
6️⃣ 함수 타입 (자료형)
이 함수는 정확히 쓰면 조금 특이합니다:
하지만 가변 매개변수는 타입 시스템에서 배열처럼 취급되므로 개념적으로는:
🔍 핵심 문법 포인트 정리
| _ | 외부 매개변수명 생략 |
| Any | 모든 타입 허용 |
| ... | 가변 매개변수 |
| = 값 | 디폴트 매개변수 |
| 반환 타입 생략 | Void |
✅ 한 줄 핵심 요약
👉 print는
**"여러 값을 받아서(separator로 이어붙이고 terminator를 붙여 출력하는 함수"**입니다.

✅ 1급 객체의 조건 (핵심 3가지)
1️⃣ 변수에 저장할 수 있다
let f = someFunction
👉 값처럼 변수에 담을 수 있어야 합니다.
2️⃣ 함수의 매개변수로 전달할 수 있다
fn()
}
👉 함수를 다른 함수에 넘길 수 있음
3️⃣ 함수의 반환값으로 사용할 수 있다
return { print("Hello") }
}
👉 함수가 함수를 만들어서 돌려줄 수도 있음
✅ 대표적인 예: 함수(Function)
많은 현대 언어에서 함수는 1급 객체입니다.
예를 들어 Swift에서는:
return a + b
}
let myFunc = add
print(myFunc(2, 3)) // 5
👉 함수 자체를 값처럼 다룰 수 있음
✅ 왜 중요한가?
이 개념이 있으면:
- 함수를 값처럼 전달 가능 → 콜백, 클로저
- 코드를 더 유연하게 구성 가능
- 함수형 프로그래밍 가능
✅ 쉽게 비유하면
- 일반 값: 숫자, 문자열 → 자유롭게 이동 가능
- 1급 객체: 숫자처럼 똑같이 다룰 수 있는 대상
👉 즉,
“변수에 담고, 넘기고, 돌려줄 수 있으면 = 1급 객체”
✅ 한 줄 정리
👉 1급 객체 = 프로그램 안에서 ‘값처럼’ 완전히 자유롭게 사용할 수 있는 대상

func up(num: Int) -> Int {
return num + 1
}
func down(num: Int) -> Int {
return num - 1
}
let toUp = up
//Swift 함수는 일급 객체로, 변수나 상수에 저장할 수 있음 print(up(num:10))
print(up(num:10))
print(down(num:5))
print(toUp(5))
//주의 : argument label인 (num:) 안 씀
// 함수를 변수에 할당하면 argument label(num:)을 생략해야 함
let toDown = down
toDown(3)
print(toDown(3))

toUp 자료형


add1의 자료형

위에는 일반 함수 호출
아래는 클로저로 호출을 하면 아규먼트레이블이 필요하지 않다.
🔥 핵심 비교 (진짜 중요)
| 이름 | 있음 (add) | 없음 |
| 저장 | 직접 사용 | 변수에 저장 |
| 타입 | (Int, Int) -> Int | 동일 |
| 호출 | add(x:y:) | add1(3,5) |

func mul(a: Int, b: Int) -> Int {
return a * b
}
let multiply = {(a: Int, b: Int) -> Int in
return a * b
}
print(mul(a:10, b:20))
print(multiply(10, 20))
let add = {(a: Int, b: Int) -> Int in
return a + b
}
print(add(10, 20))

func mul(a: Int, b: Int) -> Int {
return a * b
}
let multiply = { (a: Int, b: Int) -> Int in
return a * b
}
print(mul(a: 10, b: 20))
print(multiply(10, 20))
let add = { (a: Int, b: Int) -> Int in
return a + b
}
print(add(10, 20))
func math(x: Int, y: Int, cal: (Int, Int) -> Int) -> Int {
return cal(x, y)
}
var result = math(x: 10, y: 20, cal: add)
print(result)
result = math(x: 10, y: 20, cal: multiply)
print(result)
result = math(x: 10, y: 20, cal: { (a: Int, b: Int) -> Int in
return a + b
})
print(result)
result = math(x: 10, y: 20) { (a: Int, b: Int) -> Int in
return a + b
}
print(result)

중요(시험)

1. 클로저 기본 정의 및 사용
swift
let multiply = {(val1: Int, val2: Int) -> Int in
return val1 * val2
}
var result = multiply(10, 20)
print(result) // 200
- multiply라는 클로저 변수에 두 개의 Int를 받아 곱셈 결과를 Int로 반환하는 클로저를 할당했습니다.
- 변수처럼 호출 가능하며, 10과 20을 곱해 200을 출력합니다.
2. add 클로저 정의 및 호출
swift
let add = {(val1: Int, val2: Int) -> Int in
return val1 + val2
}
result = add(10, 20)
print(result) // 30
- 두 Int를 더하는 클로저를 add라는 상수에 할당했습니다.
- add(10, 20) 호출 시 30이 출력됩니다.
3. 함수에 클로저 타입 매개변수 전달하기
swift
func math(x: Int, y: Int, cal: (Int, Int) -> Int) -> Int {
return cal(x, y)
}
- math라는 함수는 x, y라는 Int 두 개와 (Int, Int) -> Int 타입의 클로저를 매개변수로 받습니다.
- 이 클로저 cal에 x, y를 전달하여 계산한 결과를 반환합니다.
swift
result = math(x: 10, y: 20, cal: add)
print(result) // 30
result = math(x: 10, y: 20, cal: multiply)
print(result) // 200
- 외부에서 정의한 add, multiply 클로저를 인자로 넘겨 함수 내에서 실행할 수 있습니다.
4. 클로저를 매개변수로 직접 작성하는 다양한 방법
swift
result = math(x: 10, y: 20, cal: {(val1: Int, val2: Int) -> Int in
return val1 + val2
})
print(result) // 30
- 클로저를 함수 호출 시점에 직접 정의해서 넘겨주는 방식입니다.
5. Trailing Closure (후행 클로저) 문법
swift
result = math(x: 10, y: 20) {(val1: Int, val2: Int) -> Int in
return val1 + val2
}
print(result) // 30
- 함수의 마지막 매개변수가 클로저라면 괄호 밖에 클로저 본문을 작성할 수 있는 문법입니다.
6. 매개변수 이름 생략과 축약 인자명 사용
swift
result = math(x: 10, y: 20, cal: {
return $0 + $1
})
print(result) // 30
- 클로저 매개변수 이름 없이 $0과 $1 같은 축약 인자명으로 바로 접근 가능합니다.
- return 키워드도 생략 가능하며, 한 줄이면 마지막 표현식이 반환값이 됩니다.
swift
result = math(x: 10, y: 20) { $0 + $1 }
print(result) // 30
- 가장 간결한 형태로 클로저를 작성한 예입니다.
요약
- 클로저는 함수처럼 동작하는 코드 블록이며, 변수나 상수에 할당 가능합니다.
- 함수 매개변수로 클로저를 넘겨 원하는 시점에 실행할 수 있습니다.
- Swift에서는 클로저를 생략 가능 매개변수 이름, 축약 인자명, 후행 클로저 문법 등 여러 방법으로 간결하게 작성할 수 있어 가독성과 편의성이 뛰어납니다.



수정후
class Man{
var age : Int = 0
var weight : Double
} //오류 나는 이유?
->
age와 wegiht는 프로퍼티(값)이 있어야 한다.
class Man{
var age : Int? //옵셔널 변수는 nil로 자동 초기화
var weight : Double? //옵셔널 변수는 nil로 자동 초기화
}
->
옵션널 (!,?)으로 만들면 자동으로 값이 nil 로 들어간다
class Man{
var age : Int
var weight : Double
init(){ //initializer로 초기화
age = 1
weight = 3.5
}
}

kim이 초기화 되지 않음
1.
class Man{
var age : Int = 1
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
}
var kim : Man = Man()//클래스 이름(), ()함수호출
var x : Int = 10
print(kim.age)
//var kim : Man = Man()
//kim.display() //인스턴스 메서드는 인스턴스가 호출
//print(kim.age)
2. itit 사용
class Man{
var age : Int = 1
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(){}
}
var kim : Man = Man()
print(kim.age)


default initializer(디폴트 생성자)란?
디폴트 생성자란, Swift가 클래스나 구조체의 모든 저장 속성이 기본값을 가지고 있을 때 자동으로 만들어 주는 매개변수가 없는 생성자입니다.
- 역할: 객체를 만들 때 속성을 기본값으로 초기화
- 형태: 매개변수 없는 init()
즉, 우리가 직접 init()를 안 만들어도 Swift가 자동으로 만들어 줍니다.
예시
var age: Int = 1
var weight: Double = 3.5
func display() {
print("나이=\(age), 몸무게=\(weight)")
}
}
let kim = Man() // Swift가 자동으로 만들어준 디폴트 생성자 호출
print(kim.age) // 1
kim.display() // 나이=1, 몸무게=3.5
- Man()에서 ()가 바로 디폴트 생성자 호출입니다.
- Swift가 자동으로 만들어준 init() 덕분에 별도로 정의하지 않아도 객체를 만들 수 있습니다.
2️⃣ 디폴트 생성자와 위 코드 연결
앞서 보여주신 코드에서는 이렇게 있었죠:
var age : Int = 1
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(){} // 직접 만든 생성자
}
var kim: Man = Man() // 여기가 핵심
- init(){}를 직접 만들어도, 매개변수 없는 생성자라면 디폴트 생성자와 똑같은 역할을 합니다.
- 즉, 위 코드에서 Man()는:
- 메모리 할당
- age = 1, weight = 3.5 초기화
- init() 실행 → 특별한 코드 없음
- Swift가 자동으로 만들어주는 디폴트 생성자와 기능상 동일
3️⃣ 요약
| 디폴트 생성자 | 매개변수 없는 생성자, 속성이 모두 기본값을 가지면 Swift가 자동 생성 |
| init() | 개발자가 직접 만든 생성자 |
| Man() | 객체를 생성하는 표현, 디폴트 생성자 또는 직접 만든 init() 호출 |
🔹 핵심 연결점
- Man()의 () = 디폴트 생성자 호출
- 디폴트 생성자 덕분에 매개변수 없이 객체 생성 가능
- 직접 init()를 정의하면, Swift가 자동으로 만들어주는 디폴트 생성자는 덮어쓰여집니다.

\
class Man{
var age : Int = 1
var weight : Double = 3.5
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){
self.age = age //self.을 만드시 써야 함
//매개변수 age값을 프로퍼티 age에 대입
self.weight = weight
}
}
var kim : Man = Man(age:10, weight:20.5)
kim.display()
->
class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double){
self.age = age //self.을 만드시 써야 함
//매개변수 age값을 프로퍼티 age에 대입
self.weight = weight
}
}
var kim : Man = Man(age:10, weight:20.5)
kim.display()
초기값을 생략
-------------------------------------------------------------------------------------------------------------------




오버라이드(Override)란?
오버라이드란:
상속받은 부모 클래스(슈퍼클래스)의 메서드를
자식 클래스(서브클래스)에서 재정의해서 바꾸는 것
즉, 부모 클래스의 기능을 그대로 쓰는 대신, 자식 클래스에서 새로운 동작을 정의할 수 있는 기능입니다.
2️⃣ Swift 예제
class Animal {
func speak() {
print("동물이 소리를 냅니다.")
}
}
// 자식 클래스
class Dog: Animal {
override func speak() {
print("멍멍!")
}
}
// 사용
let a = Animal()
a.speak() // 동물이 소리를 냅니다.
let d = Dog()
d.speak() // 멍멍!
3️⃣ 코드 분석
- 부모 클래스 정의
func speak() {
print("동물이 소리를 냅니다.")
}
}
- Animal 클래스는 speak()라는 메서드를 가지고 있습니다.
- 자식 클래스 정의 및 오버라이드
override func speak() {
print("멍멍!")
}
}
- Dog 클래스가 Animal을 상속(: Animal) 받습니다.
- 부모 클래스의 speak()를 재정의하려면 반드시 override 키워드를 사용해야 합니다.
- 이렇게 하면 Dog 객체가 speak()를 호출할 때 부모의 코드 대신 자식 코드가 실행됩니다.
- 오버라이드의 특징
- 부모 메서드와 같은 이름, 같은 매개변수, 같은 반환형이어야 합니다.
- override 키워드는 부모 메서드를 재정의한다는 것을 컴파일러에게 알려주는 역할
- 만약 override 없이 이름이 같으면, 컴파일 오류가 발생합니다.
4️⃣ 부모 메서드도 함께 사용하기
override func speak() {
super.speak() // 부모 클래스 메서드도 호출
print("야옹!")
}
}
let c = Cat()
c.speak()
출력:
야옹!
- super.speak() → 부모 클래스의 기능을 그대로 사용
- 그 뒤에 자식 클래스의 동작을 추가 가능
5️⃣ 한 줄 요약
오버라이드 = 부모 클래스의 메서드를 자식 클래스에서 재정의해서 원하는 동작으로 바꾸는 것
-> 부모와 같은 이름의 함수앞에 붙힌다


지정 생성자(Designated Initializer)란?
->모든 프로퍼티를 다 초기화 시켜주는 생성자(중요시험)
Designated Initializer는 클래스에서 모든 속성을 초기화하고 객체를 완전히 준비시키는 기본 생성자를 말합니다.
- 클래스에서 가장 “중심”이 되는 생성자
- 반드시 **모든 저장 속성(stored property)**를 초기화해야 함
- 다른 초기화 메서드(Convenience Initializer)를 호출할 수도 있음
Swift에서는 지정 생성자를 통해 객체를 안전하게 초기화하는 것이 핵심입니다.
2️⃣ 코드에서 지정 생성자 예시
var age: Int
var weight: Double
func display() {
print("나이=\(age), 몸무게=\(weight)")
}
init(yourAge: Int, yourWeight: Double) {
age = yourAge
weight = yourWeight
} // 이것이 지정 생성자
}
- init(yourAge: Int, yourWeight: Double)
→ 모든 속성(age, weight)을 초기화하고, 객체를 완전히 준비시킴 - 지정 생성자는 클래스에서 꼭 하나 이상 있어야 객체 생성 가능
3️⃣ 왜 var kim: Man = Man()는 오류일까?
- 이제 속성 age와 weight에 기본값이 없음
- Swift는 init()처럼 매개변수 없는 디폴트 생성자를 자동으로 만들지 못합니다.
- 반드시 모든 속성을 초기화하는 지정 생성자를 사용해야 함
kim.display()
- yourAge와 yourWeight를 넘겨주어 속성을 초기화
- 그래서 객체 생성 가능 ✅
4️⃣ 디폴트 생성자 vs 지정 생성자
| 자동 생성 | 속성에 기본값이 있을 때 | 없음, 직접 정의 필요 |
| 매개변수 | 없음 | 필요에 따라 정의 가능 |
| 목적 | 간단히 객체 생성 | 모든 속성을 안전하게 초기화 |
5️⃣ 한 줄 핵심 정리
지정 생성자 = 클래스 속성을 모두 초기화하고, 객체를 완전히 준비시키는 “주 생성자”


매소드,프로퍼티
extension Double {
var squared : Double {
return self * self
}
}
let myValue: Double = 4.0
print(myValue.squared)
print(2.0.squared) //Double형 값에도 .으로 바로 사용 가능
print(myValue.isZero)
<Extension이란?>
var squared: Double {
return self * self
}
}
- extension Double { ... }
→ 기존 타입 Double에 새로운 기능을 추가하는 것 - Swift에서는 기존 클래스, 구조체, 열거형, 기본 타입(Int, Double 등)도 확장 가능
- 여기서는 **계산 속성(Computed Property) squared**를 추가했습니다
2️⃣ 계산 속성(Computed Property) squared
return self * self
}
- self → 현재 값을 의미 (Double 타입 자신)
- self * self → 제곱 연산
- 사용 예:
print(myValue.squared) // 16.0
👉 기존 Double 타입에 제곱 기능을 바로 사용할 수 있습니다.
3️⃣ 다양한 사용 예
print(myValue.isZero) // false
- 2.0.squared → 2 * 2 = 4
- myValue.isZero → Double 타입이 원래 가지고 있는 기본 속성 isZero도 그대로 사용 가능
→ Extension으로 새 기능을 추가해도 기존 기능 손상 없음
4️⃣ 핵심 포인트
- Extension
- 기존 타입에 기능을 추가 가능
- 기존 코드를 수정하지 않아도 됨
- 계산 속성
- 값을 저장하지 않고, 접근할 때마다 계산된 값을 반환
- squared처럼 읽기 전용(get-only) 속성 가능
- self
- Extension 안에서는 현재 값을 의미
5️⃣ 한 줄 요약
이 코드는 Double 타입을 확장해서 .squared 계산 속성을 추가하고, 기존 기능(isZero)과 함께 사용할 수 있음을 보여줍니다.
xtension을 사용하는 이유
Extension은 기존 타입에 새로운 기능을 추가할 수 있는 방법입니다.
- 기존 코드를 수정하지 않고 기능 추가 가능
- 타입을 상속하지 않고도 메서드/속성 추가 가능
- 코드 재사용성, 가독성, 유지보수성을 높일 수 있음
Extension 장점
- 기존 코드 안전
- 기존 Double 코드를 건드리지 않음
- 버그 위험 최소화
- 재사용성
- 여러 곳에서 squared 기능을 반복 작성하지 않고 재사용 가능
- 가독성 향상
- x.squared → 한눈에 의미 파악 가능
- x * x보다 훨씬 직관적
- 기존 타입과 자연스럽게 통합
- 기존 isZero, rounded 같은 속성/메서드와 같이 사용 가능
Extension을 사용하는 이유
Extension은 기존 타입에 새로운 기능을 추가할 수 있는 방법입니다.
- 기존 코드를 수정하지 않고 기능 추가 가능
- 타입을 상속하지 않고도 메서드/속성 추가 가능
- 코드 재사용성, 가독성, 유지보수성을 높일 수 있음
🔹 예시로 이해
기존에 Double 타입이 있습니다:
- Swift 기본 Double에는 squared 같은 제곱 기능이 없음
- 매번 x * x라고 쓰기 귀찮음
- 이럴 때 Extension을 쓰면:
var squared: Double {
return self * self
}
}
- 이제 4.0.squared처럼 코드가 직관적이 됩니다
- 원래 Double 타입 자체는 그대로 유지됨
2️⃣ Extension 장점
- 기존 코드 안전
- 기존 Double 코드를 건드리지 않음
- 버그 위험 최소화
- 재사용성
- 여러 곳에서 squared 기능을 반복 작성하지 않고 재사용 가능
- 가독성 향상
- x.squared → 한눈에 의미 파악 가능
- x * x보다 훨씬 직관적
- 기존 타입과 자연스럽게 통합
- 기존 isZero, rounded 같은 속성/메서드와 같이 사용 가능
print(myValue.isZero) // 기존 기능

ccess Modifier란?(2문제 시험)
**Access Modifier(접근 제어자)**란:
클래스, 구조체, 변수, 함수, 속성 등 프로그램 요소의 접근 범위를 제한하는 키워드
즉, 어디서 그 코드에 접근할 수 있는지를 제어하는 장치입니다.
🔹 왜 필요할까?
- 데이터 보호 → 외부에서 마음대로 접근하지 못하도록
- 캡슐화(Encapsulation) → 객체지향 설계 원칙
- 코드 유지보수 → 내부 구현을 바꿔도 외부 코드에 영향 최소화
2️⃣ Swift에서 접근 제어자 종류
| open | 모듈 안팎에서 상속과 오버라이드 모두 가능 | open class MyClass { ... } |
| public | 모듈 외부에서도 사용 가능, 상속은 모듈 내만 가능 | public var name: String |
| internal (기본값) | 같은 모듈 내에서만 접근 가능 | var age: Int |
| fileprivate | 같은 파일 내에서만 접근 가능 | fileprivate func helper() { ... } |
| private | 같은 타입(클래스/구조체) 내에서만 접근 가능 | private var secret: String |
3️⃣ 예시로 이해
private var ssn: String // 외부에서 접근 불가
var name: String // 기본 internal
public var email: String // 외부 모듈에서도 접근 가능
init(name: String, ssn: String, email: String) {
self.name = name
self.ssn = ssn
self.email = email
}
}
let p = Person(name: "Kim", ssn: "123-45-6789", email: "kim@example.com")
print(p.name) // 가능
print(p.email) // 가능
// print(p.ssn) // 오류! private이므로 접근 불가
- ssn은 private → 외부에서 접근 불가
- name은 internal → 같은 모듈에서 접근 가능
- email은 public → 다른 모듈에서도 접근 가능
4️⃣ 핵심 포인트
- 외부 접근을 제한해 안전하게 보호
- 클래스, 구조체, 변수, 메서드, 속성 등 거의 모든 요소에 적용 가능
- Swift 기본 접근 수준은 internal
5️⃣ 한 줄 요약
Access Modifier = 코드의 접근 범위를 제한해 안전성과 캡슐화를 보장하는 키워드
| C | 없음 | C는 클래스가 없고 구조체(struct)만 있어서 접근 제어자가 없음 | N/A | N/A |
| C++ | private | 같은 클래스 안에서만 접근 가능 | 가능 | 가능 |
| protected | 같은 클래스 + 상속받은 클래스에서 접근 가능 | 가능 | 가능 | |
| public | 어디서든 접근 가능 | 가능 | 가능 | |
| C# | private | 같은 클래스 안에서만 접근 가능 | 가능 | 가능 |
| protected | 같은 클래스 + 상속 클래스에서 접근 가능 | 가능 | 가능 | |
| internal | 같은 어셈블리(Assembly) 안에서 접근 가능 | 가능 | 가능 | |
| protected internal | 상속 클래스 + 같은 어셈블리에서 접근 가능 | 가능 | 가능 | |
| public | 어디서든 접근 가능 | 가능 | 가능 | |
| Java | private | 같은 클래스 안에서만 접근 가능 | 가능 | 가능 |
| (default, 아무 modifier 없음) | 같은 패키지(package) 안에서 접근 가능 | 가능 | 가능 | |
| protected | 같은 패키지 + 상속 클래스에서 접근 가능 | 가능 | 가능 | |
| public | 어디서든 접근 가능 | 가능 | 가능 |
🔹 추가 설명
- C는 클래스가 없어서 접근 제어자가 없음
- **C++**에서는 private, protected, public만 있음
- **C#**에는 internal과 protected internal이 추가되어 모듈/어셈블리 수준 제어 가능
- Java는 default 접근 수준이 있음 (아무 modifier 없으면 같은 패키지에서만 접근 가능)
기본 접근 속성
1. swift에서는 internal이 기본접근속성
2. 최근 새로 만들어진 옵션 package
| open | 모듈 안/밖 | ✅ 가능 | 클래스, 클래스 멤버 | 다른 패키지에서도 상속/오버라이드 가능 |
| public | 모듈 안/밖 | ❌ 상속/오버라이드 제한 (모듈 내에서만 가능) | 클래스, 구조체, 열거형, 변수, 메서드 | 다른 패키지에서도 접근 가능, 상속/오버라이드는 모듈 내부만 가능 |
| internal (기본값) | 같은 모듈/패키지 안 | ✅ 가능 | 모든 타입/멤버 | 패키지 외부에서는 접근 불가 |
| fileprivate | 같은 파일 | ✅ 가능 (같은 파일 안) | 모든 타입/멤버 | 파일 외부에서는 접근 불가 |
| private | 같은 타입 | ✅ 가능 (같은 타입 안) | 모든 타입/멤버 | 타입 외부에서는 접근 불가 |
🔹 패키지 관점 요약
- Swift에서 패키지 = 모듈(Module)
- internal은 같은 패키지 안에서만 접근 가능, 패키지 외부에서는 불가
- public과 open은 패키지 외부에서도 접근 가능
- open은 상속/오버라이드까지 허용
- public은 상속/오버라이드는 모듈 내부만 가능
🔹 접근 범위 시각화
타입 내 < 파일 내 < 모듈/패키지 내 < 모듈 외부 접근 < 모듈 외부 + 상속/오버라이드

