๐ฅ ํ๋กํ ์ฝ(Protocol)
- ๊ธฐ๋ฅ์ ์ ํฉํ ๋ฉ์๋, ํ๋กํผํฐ ๋ฑ์ ๋ํ ์ฒญ์ฌ์ง์ด๋ค.
- ํด๋์ค, ๊ตฌ์กฐ์ฒด, ์ด๊ฑฐํ์ด ์ฑํ์ ํ๋ค.
์ฝ์
- ์ฑํ, ์ค์, ์ค์ฒดํ
๐ ํ๋กํ ์ฝ ์ ์
- ๊ตฌ์ฒด์ ์ธ ๊ตฌํ์ ์ฑํํ type์ด ํด์ค๋ค.
protocol SoccerTeam {
var striker: String { get set }
var midfielder: String { get set }
var defender: String { get set }
var goalKeeper: String { get set }
func play(sports: String) -> String {
}
}
๐ซง ํ๋กํ ์ฝ ํ๋กํผํฐ ์ ์ธ
- ์ฐ์ฐ ํ๋ฌํผํฐ & ์ ์ฅ ํ๋ฌํผํฐ ๋ ๋ค ๊ฐ๋ฅํ๋ค.
- ์ฐ์ฐ ํ๋ฌํผํฐ ⇒ ๋ฌด์กฐ๊ฑด var๋ก ์ ์ธ
- ์ ์ฅ ํ๋ฌํผํฐ ⇒ get, set์ ๋ฐ๋ผ์ var or let ๊ฐ๋ฅํ๋ค.
1๏ธโฃ { get } ์ผ ๊ฒฝ์ฐ
- ์๋์ ๊ฐ์ด get๋ง ์๋ค๊ณ ๊ฐ์ ํด๋ณด์.
protocol SoccerTeam {
var striker: String { get }
}
- ์ ์ฅ ํ๋ฌํผํฐ ⇒ let, var ๋ ๋ค ๊ฐ๋ฅํ๋ค.
class ATeam: SoccerTeam {
let striker: String = "Kim"
}
class BTeam: SoccerTeam {
var striker: String = "Kim"
}
- ์ฐ์ฐ ํ๋ฌํผํฐ ⇒ get only / getter setter ๋ ๋ค ๋ง๋ค์ด์ ์ฌ์ฉํด๋ ๋๋ค.
class ATeam: SoccerTeam {
var random: String = ""
var striker: String {
get {
return "kim"
}
}
}
class BTeam: SoccerTeam {
var random: String = ""
var striker: String {
get {
return "kim"
}
set {
self.random = newValue
}
}
}
2๏ธโฃ { get set } ์ผ ๊ฒฝ์ฐ
- ์๋์ ๊ฐ์ด get, set ๋ ๋ค ๊ตฌํ์คฌ๋ค๊ณ ํด๋ณด์.
protocol SoccerTeam {
var striker: String { get set }
}
- ์ ์ฅ ํ๋ฌํผํฐ ⇒ var๋ก๋ง ์ ์ธ๊ฐ๋ฅํ๋ค.
class ATeam: SoccerTeam {
var striker: String = "Kim"
}
- ์ฐ์ฐ ํ๋ฌํผํฐ ⇒ var๋ก๋ง ์ ์ธ์ด ๊ฐ๋ฅํ๊ณ , getter, setter ๋ชจ๋ ์ ๊ณตํด์ผ๋๋ค!
class BTeam: SoccerTeam {
var random: String = ""
var striker: String {
get {
return "kim"
}
set {
self.random = newValue
}
}
}
๐ ํ๋กํ ์ฝ ์ฑํ
- ์ฑํ ํ, ์ค์ ๊ตฌํ(์ค์ฒดํ)์ ์๋์ ๊ฐ์ด ํด์ค๋ค!
class ManUtd: SoccerTeam {
var striker: String = "A"
var midfielder: String = "B"
var defender: String = "C"
var goalKeeper: String = "D"
func play(sports: String) -> String {
return "Soccer"
}
}
โ๏ธ Optional ํ๋กํผํฐ
- ์๋์ ๊ฐ์ด ๊ผญ ํ์ํ์ง ์์ ํ๋กํผํฐ๋ @objc optional์ ๋ถํ์ฃผ์ด์ ์ฑํํ ๊ณณ์์ ๊ผญ ์ ์ธํด์ฃผ์ง ์์๋ ๋๋ค.
protocol SoccerTeam {
var striker: String { get set }
var midfielder: String { get set }
var defender: String { get set }
@objc optional goalKeeper: String { get set }
func play() {
print("์ถ๊ตฌํ์"
}
}
๊ทธ๋ฌ๋, ์ด๋ด ๊ฒฝ์ฐ ์ฑํํ๋ ํ์ ์ struct์ด๋ฉด ์๋๋ค! ๋ฌด์กฐ๊ฑด class๋ก! objc์ด ๋ถ์ผ๋ฉด objective-c์์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค๋ผ๋ ๋ป์ธ๋ฐ, objective-c์์๋ ๋ฌด์กฐ๊ฑด class๋ง ํ๋กํ ์ฝ ์ฑํ์ด ๊ฐ๋ฅํ๋ค. ๋ํ ์์ฐ์ค๋ฝ๊ฒ protocol์ AnyObject์ ์ฑํํ๊ฒ ๋๋ค.
โ๏ธ mutating ๋ฉ์๋
- ๊ตฌ์กฐ์ฒด์ ๊ฒฝ์ฐ, mutating์ด ํ์ํ ๊ฒฝ์ฐ protocol์ ๋ฉ์๋์์ mutating์ ๋ถํ์ค๋ค.
๐ 1๊ธ ๊ฐ์ฒด, ํ๋กํ ์ฝ
- 1๊ธ ๊ฐ์ฒด๋ ์ด๋ ํ ๊ฐ์ฒด๊ฐ ํ๋์ ๋ ๋ฆฝ์ ์ธ ํ์ ์ผ๋ก์ ์ฌ์ฉ๋ ์ ์๋ ๊ฒ์ ๋ปํ๋ค.
- ์ฆ, ํ๋กํ ์ฝ์ ํ๋์ ๋ ๋ฆฝ์ ์ธ ํ์ ์ผ๋ก ์๊ฐํ ์ ์๋ค.
๐ซง ํ๋กํ ์ฝ ํ์ ์ ์์, ๋ณ์ ํ์ ์ผ๋ก ์ ์ธํ๊ธฐ
- ์๋์ ๊ฐ์ ํ๋กํ ์ฝ์ด ์กด์ฌํ๋ค๊ณ ์๊ฐํด๋ณด์
protocol SoccerTeam {
var striker: String { get }
}
- ๊ทธ๋ฆฌ๊ณ ์๋์ ๊ฐ์ด ๋ณ์์ ํ์ ์ผ๋ก ํ๋กํ ์ฝ์ ์ ์ธํ ์ ์๋ค. ์๋ ์ด๋ป๊ฒ ์์๋ฅผ ํ๋กํ ์ฝ ํ์ ์ผ๋ก ๋ง๋ค ์ ์๋๊ณ ? 1๊ธ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ด๋ค.
let manUtd: SoccerTeam
- ์ฆ, ์์ ๋ด์ฉ์ ์์ธํ๊ฒ ํ์ด๋ณด๋ฉด ์๋์ ๊ฐ๋ค. SoccerTeam ํ๋กํ ์ฝ์ ๋ง์กฑํ๋ ๊ตฌ์กฐ์ฒด ATeam์ด ์๋ค๊ณ ๊ฐ์ ํด๋ณด์.
struct ATeam: SoccerTeam {
var striker: String = "KIM"
var midfielder: String = "LEE"
}
- ๊ทธ๋ฌ๋ฉด, ATeam์ด๋ผ๋ ๊ตฌ์กฐ์ฒด ์ธ์คํด์ค๋ฅผ ํ๋กํ ์ฝ ํ์
์ผ๋ก
ํ์ ์บ์คํ
์ด ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์ ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค. - ๋ฐ๋ผ์ ์๋์ manUtd๋ SoccerTeam ํ์ ์ด๋ฏ๋ก, midfielder ํ๋กํผํฐ์๋ ์ ๊ทผํ ์ ์๊ณ , striker ํ๋กํผํฐ์๋ง ์ ๊ทผํ ์ ์๋ค.
let manUtd: SoccerTeam = ATeam.init()
๐ซง ํ๋กํ ์ฝ ํ์ ์ ํจ์์ Parameter์ Return ํ์ ์ผ๋ก ํ์ฉํ๊ธฐ
- ์๋์ ๊ฐ์ด ํ๋กํ ์ฝ ํ์ ์ ํจ์์ parameter ํ์ ๊ณผ return ํ์ ์ผ๋ก ์ค์ ํ ์ ์๋ค.
- ๋จผ์ return์ ๊ฒฝ์ฐ ATeam struct์ ์ธ์คํด์ค๋ฅผ SoccerTeam ํ์ ์ผ๋ก ํ์ ์บ์คํ ํด์ returnํ๋ค.
- ํ๋ผ๋ฏธํฐ์ ๊ฒฝ์ฐ์๋, ATeam struct์ ์ธ์คํด์ค๋ฅผ SoccerTeam ํ์ ์ผ๋ก ํ์ ์บ์คํ ํด์ ๋ณด๋ด์ค๋ค. ๋ฐ๋ผ์ ํ๋ผ๋ฏธํฐ๋ ATeam ์ธ์คํด์ค๊ฐ ๋ค์ด๊ฐ์ผ๋๋ค.
- ์ฆ, ํ๋ผ๋ฏธํฐ์ ํ์ ์ SoccerTeam์ด๋ค. ํจ์์ ํ๋ผ๋ฏธํฐ๋ ๊ผญ SoccerTeam์ ์ฑํํ ํ์ ์ด์ฌ์ผ๋๋ค๋ ๋ป์ด๋ค. ๋ฐ๋ผ์ ์์ ATeam์ doSomething์ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ด๊ฐ ์ ์๋ค.
fun doSomething(soccerTeam: SoccerTeam) -> SoccerTeam {
return ATeam.init()
}
๐ Protocol extension
- ํ๋์ ์๋ฅผ ๊ฐ์ ํด๋ณด์.
SoccerTeam
์ ์ฑํํ๋ ์ฌ๋ฌ ๊ฐ์struct
์ด ์กด์ฌํ๋๋ฐ, ๋ชจ๋struct
์ดplay
ํจ์๋ฅผ ๊ตฌํํ ๋์ ๋์ผํ๊ฒ ๊ตฌํํ๋ค๋ฉด? - ๊ทธ๋ฌ๋ฉด ์ธ๋ฐ์์ด ๋ชจ๋
struct
์์ ๋์ผํ ์์ ์ ๋ฐ๋ณตํด์ฃผ์ด์ผ๋๋ค.
protocol SoccerTeam {
fun play()
}
// ๊ฐ์ ํจ์ play()์ธ๋ฐ, ๊ฐ struct๋ง๋ค ๋ฐ๋ณต์ ์ผ๋ก ๊ตฌํํด์ฃผ์ด์ผ๋๋ค. => ๋นํจ์จ์ !
struct ATeam: SoccerTeam {
func play() {
print("play")
}
}
struct BTeam: SoccerTeam {
func play() {
print("play")
}
}
- ์ด๋ด ๊ฒฝ์ฐ extension์ ํตํ์ฌ ํ๋กํ ์ฝ ๋ฉ์๋์ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณตํ ์ ์๋ค.
- ์ด๋ ๊ฒ ํ ๊ฒฝ์ฐ, ํด๋น ํ๋กํ ์ฝ์ ์ฑํํ ๊ณณ์์ ์ง์ play()๋ฅผ ๊ตฌํํด ์ค ํ์๊ฐ ์๋ค!
protocol SoccerTeam {
fun play()
}
extension SoccerTeam {
fun play() {
print("play")
}
}
- โผ๏ธ ๊ทธ๋ฆฌ๊ณ ๋ฉ์๋ ๋ง๊ณ ์ฐ์ฐ ํ๋กํผํฐ๋ ์์ ๊ฐ์ด extension์ผ๋ก ๋ฏธ๋ฆฌ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค!
๐ Associatedtype
- ํ๋กํ ์ฝ์์ Generic ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด? associatedtype์ ํ์ฉํด์ผ๋๋ค.
- ์๋์ ๊ฐ์ด value๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ฒ์ฉํ์ ์ ์ค์ ํ ์ ์๋ค. ์ค์ value๊ฐ ๋ฌด์จ ํ์ ์ธ์ง๋ ํด๋น protocol์ ์ฑํํ ๊ณณ์์ ์ค์ ํด์ค๋ค.
protocol SoccerTeam {
associatedtype value
func attack(value: value)
func defence() -> value
}
// SoccerTeam ์ฑํ ๋ถ
class manUTD: SoccerTeam {
func attack(value: String) {
print("\(value)๋ฅผ ๊ณต๊ฒฉํด๋ผ")
}
func defence() -> String {
return "์๋นํ์"
}
}
- ๋ง์ฝ ํ์ ์ ์ ์ฝ์ ์ฃผ๊ณ ์ถ๋ค๋ฉด?
protocol SoccerTeam {
associatedtype value: Equatable
func attack(value: value)
func defence() -> value
}
๐ซง Associatedtype์ ์ฌ์ฉํ ํ๋กํ ์ฝ ์ฑํ
- typealias๋ฅผ ํ์ฉํ์ฌ ์ด๋ค ํ์ ์ผ๋ก ํ์ฉํ ๊ฒ์ธ์ง๋ฅผ ๋ช ์ํด์ค๋ค!
struct ManUtd: SoccerTeam {
typealias value = Int
func attack(value: value) { }
func defence() -> value { ... }
}
- ๋ง์ฝ typealias ์์ด๋ ํ์ ์ถ๋ก ์ด ๊ฐ๋ฅํ๋ค๋ฉด? typealias๋ฅผ ์๋ตํด์ค๋ ๋๋ค!
struct ManUtd: SoccerTeam {
func attack(value: Int) { }
func defence() -> Int { ... }
}
๐ซง ๊ธฐ์กด ๋ฐฉ์์ผ๋ก๋ ์ ์ธํ ์ ์์๊น?
- ๋น์ฐํ ๊ฐ๋ฅํ๋ค. ์๋์ ๊ฐ์ด ์ ์ธ์ด ๊ฐ๋ฅํ๋ค.
protocol SoccerTeam {
func attack<T: Equatable>(value: T)
}
๊ทธ๋ฆฌ๊ณ , extension์ ํตํด์ ๊ธฐ๋ณธ ๊ฐ์ ๊ฐ์ง๊ฒ ํ ์ ์์๊น?
(์๋๋ ์๋ค๋์ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํ ์์์ ๋๋ค)
์๋์ ๊ฐ์ ํ๋กํ ์ฝ์ด ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
protocol Stack {
associatedtype value
func push(value: value)
}
๊ทธ๋ฆฌ๊ณ , value์ ๊ธฐ๋ณธ ๊ฐ์ ์ฃผ๊ณ ์ถ์ด์ ์๋์ ๊ฐ์ด extension์ ํตํด์ ๊ธฐ๋ณธ ๊ฐ์ ์ค๋ฒ๋ฆฌ๋ฉด ์๋ฌ๊ฐ ์๊ธฐ๊ฒ ๋๋ค.
extension Stack {
func push(value: value = 1) { // Generic parameter 'Self' could not be inferred
...
}
}
์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ ๋ ๊ฐ๊ฐ ์กด์ฌํ๋ค.
์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ด associatedType์ ํ๋กํ ์ฝ์ ์ฑํ์ํจ๋ค.
protocol Stack {
associatedtype value: BinaryInteger
func push(value: value)
}
extension Stack {
func push(value: value = 1) {
...
}
}
๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ associatedType์ด BinaryInteger๋ฅผ ์ฑํํ๊ณ ์์ ๋์๋ง extension์ด ๊ฐ๋ฅํ๊ฒ ์ ํ์ ๋ ์๋ ์๋ค.
์์ ๊ฐ์ ๊ฒฝ์ฐ๋ extension, ์ฆ ํ์ฅ์ ํ ๋๋ง BinaryInteger ์ ์ฝ์ ์ค ๊ฒ์ด๋ฏ๋ก ๋ค๋ฅธ ํ์ ์ด protocol์ ํ์ ์ผ๋ก ๋ค์ด๊ฐ๋ ๋๋ค.
๋จ, ์ด๋ด ๊ฒฝ์ฐ ์ง์ ๋ฉ์๋๋ฅผ ๊ตฌํ์ ํด์ผ๋๋ค!
extension Stack where value: BinaryInteger {
func push(value: value = 1) {
...
}
}
๊ทผ๋ฐ, ๊ทธ๋ฅ ์ด๋ ๊ฒ ์ ๋ค๋ฆญ ๋ฉ์๋๋ฅผ ํ์ฉํ ์๋ ์๋ค.
protocol Stack {
func push<T: Equatable>(value: T)
}
extension Stack {
func push<T: Equatable>(value: T = 1) {}
}
'Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ๋ฐฐ์ด ์์ ํ๊ฒ ์กฐํํ๊ธฐ (0) | 2023.02.04 |
---|---|
[Swift] Optional (0) | 2023.02.04 |
[Swift] ๋ฉํํ์ (0) | 2023.02.03 |
[Swift] Generic (0) | 2023.02.03 |
[Swift] map ์ผํ์ (map, compactMap, flatMap) (0) | 2023.02.03 |