By watching the video tutorial provided by Apple, it seems that swift is protocol-oriented programming langue and apple encourage programmers to use protocol than class. But from my personal view, I see no apparent advantages for protocol. class can conform to protocol, but they can also inherit from superclass. We can add extension to protocol, but we can also add extension to class. We can implement functions in classes which conforms to protocol, but we can also override func in subclass. I am still confused that why we need to use protocol rather than class. And when we should use protocol instead of class ?
相关问题
- What uses more memory in c++? An 2 ints or 2 funct
- Core Data lightweight migration crashes after App
- How can I implement password recovery in an iPhone
- State preservation and restoration strategies with
- “Zero out” sensitive String data in Swift
相关文章
- 现在使用swift开发ios应用好还是swift?
- UITableView dragging distance with UIRefreshContro
- Using if let syntax in switch statement
- TCC __TCCAccessRequest_block_invoke
- Where does a host app handle NSExtensionContext#co
- Enum with associated value conforming to CaseItera
- Swift - hide pickerView after value selected
- Is there a Github markdown language identifier for
Largely, it's hierarchy of types. Lets say you have an object representing a
GlowingRedCube
, but you want to have that type used in lots of generic code that cares about:Cube
extendsShape
Red
extendsColorful
Glowing
extendsIlluminated
You're in trouble. You could chose a base class and add specialisations:
GlowingRedCube
extendsGlowingCube
extendsShape
, but then you get an very wide set of classes, and an inflexible set of things (what if you wanted to make aSoftRedCube
, but keep any methods you've defined for your existing type of red cube?)You could just have
Cube
and have illumination and shape be properties, but then you don't get nice compiler type checking: if you have aRoom.lightUp()
method and have to pass it aCube
, you then need to check whether that type includes any illumination! If you could only pass it anIlluminated
then the compiler would stop you as soon as you tried.Protocols allow you to separate this:
GlowingRedCube
can implement theIlluminated
protocol, theColorful
protocol and theShape
protocol. Because of protocol extensions, you can include default implementations of functionality, so you don't have to choose a level of hierarchy to attach it to.Effectively, protocols allow you to attach behavior to an object, regardless of what else that object does. That's exactly why they're used for things like delegate and datasource protocols: even if you're mostly attaching those things to a
ViewController
, the underlying object isn't relevant, so you can be flexible about how you implement.There's a lot more to using protocols in Swift than just the basics though: they are exceptionally powerful because they can be attached to a number of different code constructs: classes, structs and enums. This allows you to really approach programming protocol first. There's a great video on this approach from WWDC last year, but it helps to have spent some time trying some different object structures yourself first to get a feel for the problems.
With protocols, one class/struct can be used as different things. For example, the
String
struct conforms to soooo many protocols!This means that
String
can be used as 11 different things! When a method needs any one of the above protocols as a parameter, you can pass in a string."But I can just create a god class that has all of the methods that the protocols have!" you argued. Remember, you can only inherit from only one class in Swift, and multiple inheritance is just so dangerous to use that it can make your code super complex.
Also, with protocols, you can define your custom behaviour of the class.
String
'shashcode
method is not the same as that ofInt
. But they are both compatible with this function:That is the true wonder of protocols.
Last but not least, protocols make sense. Protocols represent an "is a kind of" or "can be used as" relationship. When X can be used as Y, it makes sense that X conforms to protocol Y, right?
Lets take a downloading example.
You have a Base class FileDownloadModel, and have 3 subclasses AudioFileDownloadModel, VideoFileDownloadModel, and ImageDownloadModel.
You have a DownloadManager that takes a FileDownloadModel input and uses this model's urlToDownload property to download the file.
Later down the line you are told that there is one more model coming but it's of type UserDownloadModel which is a subclass of User, and not FileDownloadModel.
See now it becomes difficult to handle this scenario where you will have to change a lot of code to incorporate downloading methods.
class and protocol are orthogonal concepts. A protocol cuts across the class tree and joins one or more classes with a disparate ancestry.
Perhaps put more simply:
So you have a class Car:
and a class Color:
Now, more or less obviously Colors and Cars are completely unrelated, however, let's suppose I want to be able to easily convert either one to Strings, so I can debug with:
or
For exactly this purpose, the Swift language defines the protocol
CustomStringConvertible
so we can then declare the a Car can be printed by using that protocol:and a Color as well:
So where before I would've needed one print method for each class, now I only need one print method that looks something like:
This is possible because declaring that a class implements a protocol is a promise that I can use the methods from the protocol, knowing that they're implemented and (presumably) do what's expected.