Protocol در Swift — چیست، نحو و امکانات

نویسنده: IT Sectr منتشر شده: 2026-06-17 زمان مطالعه: 6 دقیقه

Protocol در Swift — قراردادی است که مجموعه‌ای از الزامات را تعریف می‌کند که هر نوع پذیرنده باید آنها را برآورده کند. پروتکل‌ها اساس برنامه‌نویسی پروتکل‌محور (POP) را تشکیل می‌دهند — پارادایمی که توسط Apple برای Swift در کنار OOP کلاسیک توصیه شده است. به گفته Apple Documentation, 2026، ساختارها، کلاس‌ها و enum می‌توانند پروتکل‌ها را بپذیرند که معماری را انعطاف‌پذیر و قابل آزمایش می‌کند.

نکات کلیدی

  • Protocol — قراردادی با الزامات برای ساختارها، کلاس‌ها و enum
  • Requirements شامل متدها، ویژگی‌ها، مقداردهنده‌ها و زیرنویس‌ها
  • Protocol Composition امکان ترکیب چندین پروتکل
  • POP — برنامه‌نویسی پروتکل‌محور، جایگزینی برای وراثت
  • Protocol Extensions پیاده‌سازی پیش‌فرض برای متدها اضافه می‌کنند

Protocol در Swift چیست؟

Protocol — یک رابط انتزاعی است که تعیین می‌کند یک نوع چه کارهایی باید انجام دهد، اما نه اینکه چگونه انجام دهد. در Swift، پروتکل مشابه رابط‌های Java یا Go است، اما با قابلیت‌های اضافی.

پروتکل می‌تواند نیاز داشته باشد:

  • متدها نمونه و نوع (استاتیک)
  • ویژگی‌ها با مشخص‌کننده { get } یا { get set }
  • مقداردهنده‌ها
  • زیرنویس‌ها
  • Associated types (جنریک‌ها در سطح پروتکل)

طبق WWDC 2015، Apple برنامه‌نویسی پروتکل‌محور را به عنوان رویکردی بنیادی برای معماری برنامه‌های Swift معرفی کرد. برخلاف OOP که در آن وراثت کلاس سلسله‌مراتب سفت و سختی ایجاد می‌کند، POP ترکیب پروتکل‌ها را پیشنهاد می‌دهد. این انعطاف‌پذیری می‌دهد: یک نوع می‌تواند با چندین پروتکل مطابقت داشته باشد و الزامات و پیاده‌سازی‌های آنها را از طریق extensions دریافت کند.

نحو اعلام پروتکل‌ها

Protocol با کلمه کلیدی protocol به همراه نام و بدنه اعلام می‌شود.

swift
protocol Drawable {
    func draw(context: CGContext)
    var boundingBox: CGRect { get }
}

نوع پروتکل را با دو نقطه بعد از نام می‌پذیرد:

swift
struct Circle: Drawable {
    let center: CGPoint
    let radius: CGFloat

    func draw(context: CGContext) {
        context.addArc(center: center, radius: radius, ...)
    }

    var boundingBox: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
}

یک نوع می‌تواند چندین پروتکل را با کاما بپذیرد: struct MyType: ProtocolA, ProtocolB. کامپایلر بررسی می‌کند که همه الزامات هر پروتکل برآورده شده باشند.

الزامات متدها و ویژگی‌ها

Property requirements با کلمه کلیدی var و مشخص‌کننده‌های دسترسی { get } یا { get set } مشخص می‌شوند.

swift
protocol UserProtocol {
    var name: String { get }
    var age: Int { get set }
    static var maxAge: Int { get }
    mutating func updateName(_ newName: String)
}

کلمه کلیدی mutating در پروتکل به این معنی است که متد می‌تواند self را تغییر دهد. ساختارها باید چنین متدی را به صورت mutating پیاده‌سازی کنند، کلاس‌ها می‌توانند آن را حذف کنند. Method requirements با امضای کامل شامل برچسب‌های پارامتر مشخص می‌شوند.

وراثت پروتکل‌ها

Protocol می‌تواند پروتکل دیگری را به ارث برده و الزامات جدیدی اضافه کند. این یک سلسله‌مراتب قراردادی بدون وابستگی سفت و سخت به کلاس‌ها ایجاد می‌کند.

swift
protocol Vehicle {
    var speed: Double { get set }
    func move()
}

protocol Flyable: Vehicle {
    var altitude: Double { get set }
    func takeOff()
}

نوعی که Flyable را می‌پذیرد باید الزامات هر دو پروتکل — هم Vehicle و هم Flyable — را برآورده کند. Swift از وراثت چندگانه پروتکل‌ها پشتیبانی می‌کند: protocol A: B, C.

Protocol Composition

Protocol Composition — مکانیزمی که امکان تعیین این را می‌دهد که یک نوع باید همزمان با چندین پروتکل مطابقت داشته باشد، بدون ایجاد پروتکل ترکیبی جدید.

swift
func render(_ item: Drawable & Animatable) {
    item.draw(context: ...)
    item.animate(duration: 0.3)
}

Composition (&) در پارامترهای تابع، متغیرها و محدودیت‌های جنریک کار می‌کند. کامپایلر بررسی می‌کند که نوع ارسالی همزمان همه پروتکل‌ها را برآورده می‌کند. Composition اغلب در SwiftUI استفاده می‌شود: some View — این یک generic با composition است.

Protocol Composition بر ایجاد سلسله‌مراتب وراثت ارجحیت دارد: به جای protocol A: B, C می‌توان مستقیماً B & C را پذیرفت. این انعطاف‌پذیری می‌دهد و وابستگی را کاهش می‌دهد. Composition به ویژه در پارامترهای تابع و محدودیت‌های جنریک راحت است، جایی که نیاز به ترکیب موقت الزامات بدون ایجاد پروتکل میانی است. این تعداد انواع کمکی در کد را کاهش می‌دهد.

Protocol به عنوان نوع

Protocol می‌تواند به عنوان نوع متغیر، پارامتر تابع یا عنصر مجموعه استفاده شود. این existential type نامیده می‌شود.

swift
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]

func process(drawables: [any Drawable]) {
    for item in drawables {
        item.draw(context: ...)
    }
}

کلمه کلیدی any (Swift 5.6+) به صراحت existential را نشان می‌دهد. بدون any کامپایلر اخطار می‌دهد. Swift همچنین از some (opaque types) برای پنهان کردن نوع مشخص در پشت پروتکل پشتیبانی می‌کند — این تکنیک استاندارد در SwiftUI است.

اشتباهات رایج با پروتکل‌ها

هنگام کار با protocol، توسعه‌دهندگان اغلب چندین اشتباه تکراری مرتکب می‌شوند.

  • فراموشی mutating — متد در پروتکل به عنوان mutating علامت‌گذاری شده، اما ساختار آن را بدون کلمه کلیدی پیاده‌سازی می‌کند
  • Protocol as type به جای generic — استفاده از Drawable به جای <T: Drawable> در جایی که نوع مشخصی نیاز است
  • Circular protocol reference — پروتکلی که از طریق associated type به خود ارجاع می‌دهد، بدون راه‌حل صحیح
  • Class-only protocol — استفاده از AnyObject بدون نیاز، که struct و enum را حذف می‌کند

سوالات متداول

تفاوت protocol با abstract class چیست؟

Protocol فقط الزامات را بدون پیاده‌سازی تعریف می‌کند (تا قبل از protocol extensions). Abstract class می‌تواند پیاده‌سازی و حالت داشته باشد. در Swift کلاس‌های انتزاعی وجود ندارند — نقش آنها را پروتکل‌ها با extensions ایفا می‌کنند.

آیا struct می‌تواند protocol را بپذیرد؟

بله، ساختارها، کلاس‌ها و enum — همه می‌توانند پروتکل‌ها را بپذیرند. این اساس POP است: شما مجبور به استفاده از کلاس‌ها برای سازماندهی معماری نیستید. ساختارها با پروتکل‌ها معناشناسی مقدار و تغییرناپذیری را فراهم می‌کنند.

associated type در پروتکل چیست؟

Associated type (associatedtype) — placeholder برای نوعی است که نوع پیاده‌کننده خودش تعیین می‌کند. مثال: Collection دارای associatedtype Element است. این generic در سطح پروتکل است.

آیا می‌توان پروتکل را فقط برای کلاس‌ها محدود کرد؟

بله، وراثت از AnyObject اضافه کنید: protocol MyProtocol: AnyObject. در این صورت فقط کلاس‌ها می‌توانند این پروتکل را بپذیرند. این برای مراجع weak و delegate‌ها مفید است.

چگونه مطابقت با پروتکل را در runtime بررسی کنیم؟

از is برای بررسی و as? برای تبدیل استفاده کنید: if let drawable = item as? Drawable. این فقط برای پروتکل‌های بدون associated types کار می‌کند.

خلاصه

  • Protocol — قراردادی برای متدها، ویژگی‌ها، مقداردهنده‌ها و زیرنویس‌ها
  • Class, struct, enum — همه انواع می‌توانند پروتکل‌ها را بپذیرند
  • وراثت پروتکل‌ها سلسله‌مراتب قراردادی بدون وابستگی سفت و سخت ایجاد می‌کند
  • Protocol Composition (&) پروتکل‌ها را بدون وراثت ترکیب می‌کند
  • Existential types (any) و opaque types (some) — دو روش کار با پروتکل‌ها
  • POP توسط Apple به عنوان جایگزینی برای وراثت کلاسیک کلاس‌ها توصیه شده است
  • Protocol Extensions امکان اضافه کردن پیاده‌سازی‌های پیش‌فرض را فراهم می‌کنند

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید