Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions TSPL.docc/LanguageGuide/Protocols.md
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,68 @@ that tries to adopt `SomeClassOnlyProtocol`.
TODO: a Cacheable protocol might make a good example here?
-->

You can also name a specific class in a protocol's inheritance list
to require that all conforming types are subclasses of that class.

```swift
class Renderer {
func render(_ text: String) { print(text) }
}

protocol Widget: Renderer {
var title: String { get }
}

extension Widget {
func display() { render(title) }
}

class ButtonWidget: Renderer, Widget {
var title: String
init(title: String) { self.title = title }
}

let button = ButtonWidget(title: "OK")
button.display()
// Prints "OK"
```

<!--
- test: `classNameInProtocol`

```swifttest
-> class Renderer {
func render(_ text: String) { print(text) }
}

-> protocol Widget: Renderer {
var title: String { get }
}

-> extension Widget {
func display() { render(title) }
}

-> class ButtonWidget: Renderer, Widget {
var title: String
init(title: String) { self.title = title }
}

-> let button = ButtonWidget(title: "OK")
-> button.display()
<- OK
```
-->

In the example above, `Widget` can only be adopted by subclasses of `Renderer`.
Because the protocol guarantees that every conforming type is a `Renderer` subclass,
the `Widget` protocol extension can call `render(_:)` directly.
This is more restrictive than using `AnyObject`:
it limits conformance to a specific class hierarchy,
not just any class type.
Use this when the protocol's implementation
depends on the concrete behavior of a particular base class.

## Protocol Composition

It can be useful to require a type to conform to multiple protocols at the same time.
Expand Down
28 changes: 28 additions & 0 deletions TSPL.docc/ReferenceManual/Declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,34 @@ can likewise be adopted only by class types.
> the `AnyObject` requirement is implicitly applied to that protocol;
> there’s no need to mark the protocol with the `AnyObject` requirement explicitly.

You can also name a specific class in the *inherited protocols* list
to restrict adoption of the protocol to subclasses of that class.
For example, the following protocol can be adopted only by subclasses of `SomeBaseClass`:

```swift
class SomeBaseClass { /* ... */ }
protocol SomeRefinedProtocol: SomeBaseClass {
/* Protocol members go here */
}
```

<!--
- test: `protocol-declaration-superclass`

```swifttest
-> class SomeBaseClass {}
-> protocol SomeRefinedProtocol: SomeBaseClass {
/* Protocol members go here */
}
```
-->

This is more restrictive than using `AnyObject`
because it limits conformance to a specific class hierarchy
rather than to any class type.
For more information,
see <doc:Protocols#Class-Only-Protocols>.
Comment on lines +2462 to +2466

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this paragraph. The reference doesn't follow the three-part "intro, code listing, walkthrough" format that the guide uses. The reference generally doesn't link to the guide, except in places where only the chapter in the guide has the full information.


Protocols are named types, and thus they can appear in all the same places
in your code as other named types, as discussed in <doc:Protocols#Protocols-as-Types>.
However,
Expand Down