Swift Learning-25--Protocol 02

Source: Internet
Author: User
Tags extend

Adding protocol consistency through extensions

Even if the source code cannot be modified, the extension can be used to follow the existing type and conform to the Protocol, and the extension may add attributes, methods, subscripts, and constructors to the existing types, so that they can meet the requirements in the Protocol

Note: When an existing type is followed by an extension and complies with the agreement, all forces of that type will also be given the functions defined in the agreement

Protocol textrepresentbble{

var textualdescription:string {Get}

}

You can extend the existing class Dice to comply with the Textrepresentable protocol:

Extension dice:textoutputstream{

var textualdescription:string{

Return "DDDDD"

//     }

// }

By extending compliance and compliance with the Protocol, and in the same way that the original definition follows and conforms to the agreement, the protocol name is written after the type name, separated by a colon, and then implemented within the extended curly braces for the contents of the protocol requirements

Adherence to protocols through extensions

When a type has met all of the requirements in an agreement, but has not yet declared that it follows the protocol, it can be followed by an empty extender:

struct hamster{

var name:string

var textualdescription:string {

Return "A hamster named \ (name)"

}

}

Extension hamster:textrepresentbble{}

From now on, Hamster instances can be used as textrepresentable types

Let Simonthehamster = Hamster.init (name: "Simon")

Let somethingtextrepresentable:textrepresentbble = Simonthehamster

Print (somethingtextrepresentable.textualdescription)

Note: Even if all of the requirements of the Protocol are met, the type does not automatically follow the protocol and must be explicitly adhered to

A collection of protocol types

The protocol type can be used in collections such as arrays or dictionaries

Let things: [textrepresentbble] = [Simonthehamster]

As shown below, you can conveniently things an array and print text information for each element

For thing in things {

Print (thing.textualdescription)

}

Thing is a textrepresentbble type, not a Hamster type, even if the instance is actually one of these types in the background, because thing is the textrepresentbble type, any textrepresentbble Instances have a textualdescription attribute, so it is safe to ask thing.textualdescription in each loop

Inheritance of agreements

The protocol can inherit one or more other protocols, which can add new requirements on the basis of inherited protocols, the inheritance syntax of the protocol is very similar to the inheritance of the class, and multiple inherited protocols are separated by (,)

Protocol Inheritingprotocol:someprotocol, anotherprotocl{

Here is the definition part of the protocol.

// }

As shown in the following example:

Protocol prettytextrepresentable:textrepresentbble{

var prettytextualdescription:string {Get}

}

The example defines a new protocol prettytextrepresentable, which inherits from the Textrepresentable protocol, and any type of prettytextrepresentable laundry that complies with the requirements of the Protocol must also meet Textrepresentbble The requirements of the agreement.

Extension Snakesandladders:prettytextrepresentable {

var prettytextualdescription:string {

var output = textualdescription + ": \ n"

For index in 1...finalSquare {

Switch Board[index] {

Case let ladder where ladder > 0:

Output + = "▲"

Case Let Snake where Snake < 0:

Output + = ""

Default

Output + = "0"

//            }

//        }

Return output

//    }

//}

The above extension enables Snakesandladders to follow the Prettytextrepresentable protocol and provides the Prettytextualdescription attribute required by the protocol. Each prettytextrepresentable type is also a textrepresentable type, so the Textualdescription property can be accessed in the implementation of Prettytextualdescription.

Class type Exclusive protocol

You can restrict a protocol to be followed by a class type by adding the class keyword in the list of inherited protocols, and the class keyword must first appear in the inheritance list of the protocol before other inherited protocols:

Protocol Someclassonlyprotocol:class, Someinheritedprotocol {

Here is the definition part of the class type exclusive protocol

// }

In the above example, the protocol Someclassonlyprotocol can only be followed by a class type, and if an attempt is made to keep the struct or enum type following the protocol, a compilation error will result

Note: When the requirements of the Protocol definition require that the type of protocol to be followed must be reference semantics rather than value semantics, the class-type exclusive protocol should be used

Protocol synthesis

Sometimes you need to follow multiple protocols simultaneously, and you can combine multiple protocols in a format such as Someprotocol & Antherprotocol, called Protocol compositing. You can list any number of protocols you want to follow in order to split with symbols (&)

Protocol named{

var name:string{get}

}

Protocol aged{

var age:int {Get}

}

struct person:named,aged{

var name:string

var age:int

}

Func Wishhappybirthday (to Celebrator:named & aged) {

Print ("Happy birthday, \ (celebrator.name), you ' re \ (celebrator.age)")

}

Let Birthdayperson = Person.init (name: "Malcolm", age:21)

Wishhappybirthday (To:birthdayperson)

The Named protocol contains the Name property of type String, the aged protocol contains an age property of type Int, and the person struct follows the two protocols

Wishhappybirthday (to:) The type of the parameter celebrator of the function is Named & aged, which means that it does not care about the specific type of the parameter, as long as the parameter conforms to both protocols

Note: Protocol compositing does not generate a new, permanent protocol, but rather synthesizes multiple protocols into a temporary protocol that is only valid in a local scope

Check the consistency of the Protocol

You can use the IS and as operators described in type conversions to check the consistency of the Protocol, that is, if a protocol is met, and you can specify a transition to the specified protocol type, and the check is very much translated to a protocol type that is syntactically and type-checked and transformed in exactly the same way:

is used to check if the vision conforms to a protocol and returns false if True

As? Returns an optional value that returns the optional value of the protocol type when the instance conforms to a protocol, otherwise returns nil

as! To force an instance down to a protocol type that throws a run-time error if the cast fails

Protocol hasarea{

var area:double {Get}

}

Class circle:hasarea{

Let pi = 3.1415927

var radius:double

var area:double{

return pi * radius * radius

}

Init (radius:double) {

Self.radius = Radius

}

}

Class country:hasarea{

var area:double

Init (area:double) {

Self.area = Area

}

}

The Circle class implements the area attribute as a computed property based on the storage-type attribute radius, and the country class implements the area property as a stored property, which all two classes correctly conform to the Hasarea protocol

The following is a class that does not follow the Hasarea protocol

Class animal{

var legs:int

Init (legs:int) {

Self.legs = Legs

}

}

Circle. Country, Animal does not have a common base class, however, they are all classes, and their instances can be stored in the same array as the value of the Anyobject type:

Let objects: [anyobject] = [

Circle.init (radius:2.0),

Country.init (area:243_610),

Animal.init (Legs:4)

]

For object in Objects {

If let Objectwitharea = object as? Hasarea {

Print ("area is \ (Objectwitharea.area)")

}else{

Print ("Something that doesn ' t has an area")

}

}

When an iterative element conforms to the Hasarea protocol, the as? The optional value returned by the operator is bound to the Objectwitharea constant by an optional binding, Objectwithaera is an instance of the Hasarea protocol type, so the area property can be accessed and printed

The types of elements in the objects array do not lose type information because of strong, they are still Circle, country, Animal types, however, when they are assigned to Objectwitharea constants, they are only considered hasarea types, so Only area properties are accessed

Optional Protocol requirements

The protocol can define optional requirements. Following the type of protocol you can choose whether to implement these requirements, use the optional keyword as a prefix in the protocol to define optional requirements, optional requirements in the code you need to deal with OC, the protocol and optional requirements must take @objc attribute, the protocol that marks @objc attribute can only be inherited from the O Class C classes or @objc classes follow, and other classes and structs and enumerations cannot follow this Protocol

When you use optional requirements (for example, optional methods or properties), their types automatically become optional, for example, a string of type (int), which becomes a string ((int)), it is important to note that the entire function type is optional and not Is the return value is optional

The optional requirements in the protocol can be used with optional chaining, because the type of protocol that follows may not implement these optional requirements, like Someoptionalmethod? (someargument) So you can add it after the optional method name? To invoke an optional method.

@objc Protocol counterdatasource{

@objc optional func incrementforcount (count:int), Int

@objc Optional var fixedincrement:int {get}

}

Note: Strictly speaking, the methods and properties in the Counterdatasource protocol are optional, so classes that follow the protocol may not implement these requirements, although it is technically permissible to do so, but do not write

Class counter{

var count = 0

var datasource:counterdatasource?

Func increment () {

If let amount = DataSource?. Incrementforcount? (Count:count) {

Count + = Amount

}else if let amount = DataSource?. fixedincrement{

Count + = Amount

}

}

}

Protocol Extensions

Protocols can be extended to provide properties, methods, and subscript implementations for types that follow the protocol, and you can implement these functions based on the protocol itself, without having to repeat the same implementation in each type of protocol that follows it, or using global functions

For example.

Extension Someprotocol {

Func Randombool (), Bool {

return random () > 0.5

//    }

//}

With protocol extensions, all types that follow the protocol are automatically given the added method implementation of this extension without any additional modifications

Provide a default implementation

Protocol extensions can be used to provide a default implementation for the properties, methods, and subscripts required by the protocol, and if the type of protocol is followed to provide its own implementation for these requirements, then these custom implementations will be substituted for the default implementation in the extension

Note: The default implementation and optional Protocol requirements provided by Protocol extensions differ, although in both cases classes that follow the protocol do not have to implement these requirements on their own, but the default implementation provided by the extension can be called directly without the use of optional chained calls

Extension prettytextrepresentable{

var prettytextualdescription:string {

Return textualdescription

}

}

Add a throttling condition for an extension agreement

When extending an agreement, you can specify a number of constraints, only if the type that follows the agreement satisfies those restrictions. To obtain the default implementation provided by the Protocol extension, the protocol restriction is written after the protocol name, and is described using the Whrer clause.

For example, you can extend the CollectionType protocol, but only for elements in the collection that follow the Textrepresentable protocol:

Extension CollectionType where generator.element:textrepresentbble{

Extending the content of a protocol definition

// }

Swift Learning-25--Protocol 02

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.