접근제어자
open
- 모든 외부 모듈에서 접근할 수 있는 접근제어자
- 가장 개방적인 접근 수준
- 유일하게
class 에서만 사용 가능
public
- 모든 외부 모듈에서 접근할 수 있는 접근제어자
- 가장 개방적인 접근 수준
internal
기본값 접근제어자로 설정하지 않았다면 internal
- 동일한 모듈에서 접근 가능
fileprivate
- 동일한 파일 내부에서만 접근할 수 있는 접근 제어자
private
- 가장 제한적인 접근 제어자
- 해당 요소를 선언한 스코프(예를 들어 class, struct, enum의 코드블록)에서만 사용 가능
struct 에서 private 프로퍼티가 있다면 멤버와이즈 init을 사용할 수 없어서 직접 init을 작성해야 합니다.
모듈이란?
- 모듈은 코드 배포의 단일 단위입니다.
- Swift에서는 import를 사용하여 다른 모듈에서 가져올 수 있습니다.
프로토콜
프로토콜 자체는 기능을 구현하지 않으며, 오직 설계만 제공합니다.
class, struct, enum 에서 프로토콜을 채택할 수 있으며, 프로토콜에서 정의한 프로퍼티와 메소드를 모두 구현해야 합니다.
- 프로토콜을
채택하는 방법은 타입의 이름 뒤에 : 콜론을 넣은 후 프로토콜 이름을 작성하면 됩니다.
- 프로토콜은 여러 개를
채택 할 수 있으며, 프로토콜 이름을 , 로 구분합니다.
프로토콜에서 정의된 프로퍼티는 항상 var 로 선언되어야 합니다.
프로토콜에서 정의하는 프로퍼티는 읽기 전용 { get } 또는 읽기-쓰기 가능 { get set } 으로 설정할 수 있습니다.
{ get } 으로만 설정해도 프로퍼티의 값을 변경할 수 있지만, 명시적으로 작성하면 코드의 의도를
쉽게 파악할 수 있습니다.
- 프로토콜에서 정의하는 메소드는
이름,파라미터, 리턴타입만 선언하며, 구현부 { } 는 작성하지 않습니다.
- Swift에서 프로토콜은 다른 언어에서 말하는 인터페이스 개념과 유사합니다.
protocol FullyNamed {
var fullName: String { get }
func sayMyFullName() -> String
}
class Person: FullyNamed {
var fullName: String
func sayMyFullName() -> String {
return fullName
}
init(fullName: String) {
self.fullName = fullName
}
}
var person = Person(fullName: "Brody")
print(person.fullName)
print(person.sayMyFullName())
protocol FullyNamed {
var fullName: String { get }
func sayMyFullName() -> String
}
protocol ShortNamed {
var shortName: String { get }
}
class Person: FullyNamed, ShortNamed {
var fullName: String
func sayMyFullName() -> String {
return fullName
}
var shortName: String {
return "ShortName"
}
init(fullName: String) {
self.fullName = fullName
}
}
var person = Person(fullName: "Brody")
print(person.fullName)
print(person.sayMyFullName())
print(person.shortName)
확장
- 기존의
class, struct, enum, protocol 타입에 새로운 기능을 추가할 수 있는 키워드입니다.
- 타입의 원본 코드를 수정하지 않고도 수평적인 기능을
확장 할 수 있어 코드의 유지 보수와 가독성이 향상됩니다.
extension 키워드를 사용하여 기존 타입을 확장할 수 있습니다.
- 하나 이상의 프로토콜을
extension으로 추가해 적용할 수 있습니다.
이를 통해 기존 타입을 수정하지 않고 프로토콜 요구사항을 구현할 수 있어 코드 유지보수가 편리해집니다.
- 하나의 타입에
extension 여러 번 가능합니다.
- 확장할 수 있는 것들은 아래와 같습니다.
- 연산 프로퍼티
- 확장된 곳에서 저장 프로퍼티는 사용할 수 없습니다.
- 메소드
- 새로운 초기화
init
- 중첩된 타입(Nested Type)
struct Person {
let lastName: String
let firstName: String
let age: Int
}
protocol FullyNamed {
var fullName: String { get }
func sayMyFullName() -> String
}
extension Person {
var nameAge: String {
return "\(firstName)(\(age)세)"
}
}
extension Person {
func sayHello() {
print("\(firstName)님 안녕하세요?")
}
}
extension Person: FullyNamed {
var fullName: String {
return "\(lastName)\(firstName)"
}
func sayMyFullName() -> String {
return "제 이름은 \(fullName)입니다."
}
}
let person = Person(lastName: "홍", firstName: "길동", age: 20)
print(person.nameAge)
person.sayHello()
print(person.fullName)
print(person.sayMyFullName())