Protocol is a set of requirements (properties and methods) that a type adopting the protocol must conform to. In Swift, protocols are the central element of Protocol-Oriented Programming (POP), enabling polymorphism without inheritance. According to Swift.org (2025), protocols are used in 85% of the types in the Swift standard library. In Objective-C, @protocol plays a similar role, but with a limitation — classes only.
Key Takeaways
Protocol in Swift is an abstract interface defining requirements that a type must satisfy. A protocol can require properties (with getter/setter), methods (instance and type), initializers, and subscripts. Unlike classes, protocols can be adopted by structures, enumerations, and classes — providing flexibility unavailable in purely class-based languages.
protocol Drawable {
var boundingRect: CGRect { get }
mutating func draw(in context: CGContext)
}
struct Circle: Drawable {
var center: CGPoint
var radius: CGFloat
var boundingRect: CGRect {
CGRect(x: center.x - radius, y: center.y - radius,
width: radius * 2, height: radius * 2)
}
func draw(in context: CGContext) {
context.addEllipse(in: boundingRect)
}
}The Circle structure adopts the Drawable protocol, providing the boundingRect property and the draw(in:) method. Thanks to the protocol, any shape implementing Drawable can be handled uniformly — this is polymorphism without inheriting from a common base class.
Protocol-Oriented Programming (POP) is a paradigm introduced by Apple at WWDC 2015 as an alternative to class-based inheritance. In POP, protocols are the primary abstraction tool, and protocol extensions provide default implementations. This solves the «diamond inheritance» problem and allows extending existing types without modifying source code.
| Aspect | POP (Protocol-Oriented) | OOP (Class-based) |
|---|---|---|
| Abstraction unit | Protocol | Base class |
| Reuse mechanism | Protocol extension | Inheritance |
| Value types | Supported (struct) | Reference types only |
| Multiple adoption | Protocol composition | Multiple inheritance (not in Swift) |
| Coupling risk | Low (loose coupling) | High (rigid hierarchy) |
According to the Apple Swift blog (2025), structs account for 70% of types in modern Swift applications. POP is a key reason for this shift: protocols allow structs to gain polymorphic behavior without switching to classes.
Swift protocols occupy a middle ground between Java interfaces and C++ abstract classes. They can contain implementations (via extensions) but cannot hold state (stored properties). Let's examine the differences across three languages.
| Characteristic | Swift Protocol | Java Interface | C++ Abstract Class |
|---|---|---|---|
| Method implementation | Yes (extension) | Yes (default methods) | Yes |
| Stored properties | No | No | Yes |
| Value types | Yes | No | No |
| Multiple implementation | Yes | Yes | Yes |
| Initializers | Yes (requirements) | No | Yes |
Key difference: Swift Protocol can require initializers and subscripts, which is not available in Java Interface. However, a protocol cannot store state — this remains the responsibility of the type adopting the protocol.
Associated Type is a generic type within a protocol that gets concretized by the adopting type. This allows creating type-safe protocols without specifying a concrete data type. Associated types work in tandem with Swift generics.
protocol Container {
associatedtype Item
var count: Int { get }
mutating func append(_ item: Item)
subscript(i: Int) -> Item { get }
}
struct IntStack: Container {
var items: [Int] = []
var count: Int { items.count }
typealias Item = Int
mutating func append(_ item: Int) {
items.append(item)
}
subscript(i: Int) -> Int {
items[i]
}
}
func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
// function body
}Container is a protocol with associatedtype Item. IntStack implements it by specifying typealias Item = Int. The generic function sum uses a where-clause to work only with numeric containers. Associated types make protocols generic without losing type safety.
Protocol composition — combining multiple protocols via the & operator. A type conforming to a composition must implement all combined protocols. This replaces multiple inheritance, which is absent in Swift, and allows precise specification of requirements for function parameters.
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }
struct Person: Named, Aged {
let name: String
let age: Int
}
func greet(_ entity: Named & Aged) {
print("Hello, \(entity.name), age \(entity.age)!")
}
// Protocol extension — default implementation
extension Named {
func introduce() {
print("My name is \(name)")
}
}Protocol extension provides default method implementations. A type adopting the protocol can override the extension method — in that case, its own implementation is called. This is the mechanism by which Swift implements optional methods without @objc.
@protocol in Objective-C is the predecessor of Swift Protocol, but with significant limitations. Objective-C protocols are only available for classes (not structs or enumerations) and use dynamic dispatch via message passing. Methods can be @required (default) or @optional.
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end
@interface ConsoleLogger : NSObject
@end
@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
NSLog(@"[LOG] %@", message);
}
@endUnlike Swift, Objective-C protocols do not support associated types, generics, protocol extensions, or value types. They remain a mechanism for class-based abstraction, while Swift Protocol is a full-featured polymorphism tool for all types.
Frequently Asked Questions
Protocol cannot store state (stored properties) — only property requirements. An abstract class can contain data fields. A protocol can be adopted by structs and enumerations, while an abstract class can only be subclassed by classes. In Swift, protocols are the primary abstraction tool, classes are used less frequently.
POP is a paradigm where protocols and protocol extensions replace deep inheritance hierarchies. Instead of a base class from which all subclasses inherit, POP uses protocol composition with default implementations via extension. This reduces coupling and improves code reusability.
Yes, Swift protocols support inheritance. protocol SerializableDrawable: Drawable, Codable — a protocol combining the requirements of Drawable and Codable. A type adopting SerializableDrawable must fulfill the requirements of all protocols in the hierarchy. This differs from class inheritance — protocols do not have a common ancestor.
some (opaque type) guarantees that a function returns one specific type conforming to the protocol. any (existential type) allows storing any type that conforms to the protocol. some is used to preserve type identity, any — for heterogeneous collections. some appeared in Swift 5.1, any — in Swift 5.7.
Use is for checking and as? for casting: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. In Objective-C, conformsToProtocol: is used. Swift also supports is-checking for protocols without associated types.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also