import UIKit
var str = "Hello, playground"
//协议:方法、属性、或者一个功能的的声明(没有实现)
//协议可以被类,结构体,枚举使用而实现具体的方法
//任何满足协议需求的类型,被称为尊从该协议
protocol AProtocol {
}
protocol BProtocol {
}
//一个结构体或者类尊从多个协议,用逗号分隔开
struct AStruct : AProtocol,BProtocol {
}
class Name {
}
//超类Name写在协议AProtocol之前,常规操作
class GivenName : Name ,AProtocol ,BProtocol {
}
//结构体和枚举不能继承,但是结构体和枚举能够遵从协议,达到一个继承的目的,而协议的遵从,就类似于只要我遵从的协议的一小块功能。这样灵活一点
//属性协议,用的最多了
//要求实现getter方法(setter可选),属性必须定义为变量
//属性协议
protocol FileAccessPriority {
var readOnly : Bool { get }
var readWrite : Bool {get set}
}
protocol AccessUrl {
static var link: String { get }
}
protocol FullName {
var fName : String {get}
var gName : String {get}
}
struct Student : FullName {
var fName: String
var gName: String
}
struct Teacher : FullName {
var fName: String
var gName: String
}
var student1 = Student(fName: "小明", gName: "王")
student1.fName
student1.gName
class SSomeBody : FullName {
var title:String?
var name: String
init(title: String?, name:String) {
self.title = title
self.name = name
}
var gName: String {
return name
}
var fName: String {
return title ?? "无名人士"
}
var desc : String {
return self.fName + self.gName
}
}
var sombody1 = SSomeBody(title: "大帝", name: "亚历山大")
sombody1.gName
sombody1.fName
var nobody1 = SSomeBody(title: nil, name: "小波")
nobody1.fName
nobody1.gName
//方法协议
//让类,结构体,枚举分解为更小的组合
//类型方法写协议 前缀总是static
protocol AMethod {
static func foo()
}
class A :AMethod {
// 不可被继承
static func foo() {
print("aaa aaa ")
}
// 可被继承
// class func foo() {
// print("bbb")
// }
}
import Foundation
//实例方法协议
//产生随机数
protocol RandomGeneratable {
func randomNumber() -> Int
}
struct RandomNumber : RandomGeneratable {
func randomNumber() -> Int {
return Int(arc4random())
}
}
let random1 = RandomNumber()
random1.randomNumber()
struct RnadomNumberInSix : RandomGeneratable {
func randomNumber() -> Int {
return Int(arc4random()) % 6 + 1
}
}
let random2 = RnadomNumberInSix()
random2.randomNumber()
//结构体,枚举 编译方法协议 需要更改的时候需要添加mutating
protocol Switchable {
mutating func onoff()
}
enum MySwitch : Switchable {
case on,off
mutating func onoff() {
switch self {
case .off:
self = .on
default:
self = .off
}
}
}
//构造方法协议
//可以要求遵从者实现指定的构造方法,实现时用required init,编译时候会提示添加,无需手动添加required,不常用
protocol C {
init(c: Int)
}
struct D : C {
init(c: Int) {
}
}
class E : C {
required init(c: Int) {
}
}
//协议作为类型使用***
//可用于参数类型,返回类型,变量,常量,属性,集合类型中的元素类型
class MyRandomNumber : RandomGeneratable {
func randomNumber() -> Int {
return Int(arc4random()) % 10 + 1
}
}
struct Dice {
var sides : Int
var randomNumber : RandomGeneratable
func play() -> Int {
return self.randomNumber.randomNumber() % sides + 1
}
}
let aDice = Dice(sides: 99, randomNumber: RandomNumber())
aDice.play()
//协议作为代理使用
//协议作为代理:代理是一种常见的设计模式,可以让类或者结构体把一部分职责,指派给非同类的实例去承担。
//要寻求代理,可以通过定义一个协议,打包要实现的职责在协议中。
//该代理协议的遵从者,就可以实现这些打包的职责
//代理在iOS开发中,一般可以用于响应特定的操作,或从外部数据源取回数据,但无需了解是何种数据源
struct Role {
var name : String
}
protocol Player {
var role : Role {get}
mutating func Play()
}
protocol GameDelegate {
func start(with player : Player) -> Int
func rolePK(with player : Player, armed :Bool) -> Int
func end(with player : Player ) -> Int
}
struct GameAgent : GameDelegate {
func start(with player: Player) -> Int {
print(player.role.name, "开始进入游戏,获得经验2000")
return 2000
}
func rolePK(with player: Player, armed: Bool) -> Int {
if armed {
print(player.role.name,"开始PK,您有武器,获得经验5000")
return 5000
}else {
print(player.role.name,"开始pk","您没有武器,获得经验2500")
return 2500
}
}
func end(with player: Player) -> Int {
print(player.role.name,"正常退出,获得经验1000")
return 1000
}
}
struct MirPlayer : Player {
var exp : Int
var gameAgent : GameAgent?
var role: Role
mutating func Play() {
if let gameAgent = gameAgent {
print("您使用了代玩")
exp += gameAgent.start(with: self)
exp += gameAgent.rolePK(with: self, armed: true)
exp += gameAgent.end(with: self)
}else {
print("您没有使用,不能自动升级")
}
}
}
let role = Role(name: "小波")
var playerN = MirPlayer(exp: 0, gameAgent: nil, role: role)
playerN.Play()
let role2 = Role(name: "土豪玩家")
let agent = GameAgent()
var palyerE = MirPlayer(exp: 0, gameAgent: agent, role: role2)
palyerE.Play()
//协议的扩展和协议的约束
//协议扩展:给无源码的添加协议(给系统类添加协议)
let a = 1
protocol ShowHint {
func hint() -> String
}
extension Int : ShowHint {
func hint() -> String {
return "整数:\(self)"
}
}
a.hint()
(-1).hint()
//如果一个类型预遵从了协议,可以直接扩展协议
struct Lesson {
var name : String
var description : String {
return "课程名是:" + name
}
}
1.description
//extension Lesson : CustomStringConvertible{
// var description: String {
// retu
// }
//}
//扩展约束:可以在扩展协议的同时,加上限定条件.where语句
extension ShowHint where Self: CustomStringConvertible {
func hint2() -> String {
return "我是一个能显示成字符串的类型" + self.description
}
}
1.hint2()
//集合类型Collection也是一种协议Iterator.Element指代其中的元素
let array = [1,2,3,4,5]
extension Collection where Iterator.Element :CustomStringConvertible {
func newDesc() -> String {
let itemAsText = self.map{ $0.description }
return "该集合类型元素数目是\(self.count),元素的值依次是" + itemAsText.joined(separator: ",")
}
}
array.newDesc()
print(array)
//协议集合类型,因为协议可以作为类型使用,可以把遵从相同协议的实例放到一个协议类型的数组
let arry:[CustomStringConvertible] = [1,2,3,"hha"]
for element in arry {
print(element)
}
//协议继承和默认实现
//class不能多重继承,结构体进行协议扩展,相当于多重继承
protocol MyPrintable : CustomStringConvertible, CustomPlaygroundDisplayConvertible {
}
//
struct MyContent {
var text : String
var mycustomtext : String
}
extension MyPrintable {
var playgroundDescription: Any {
return "PlayfroundQuickLook is departure"
}
}
//提供默认实现,不需要每个继承他的结构体和枚举都具体实现
extension MyContent : MyPrintable {
var playgroundDescription: Any {
return self.mycustomtext
}
var description: String {
return self.text
}
}
let mycontent1 = MyContent(text: "内容", mycustomtext: "保留文字")
mycontent1.description
//swift中协议继承,提倡多协议组合的做法
//类专用协议 多加个关键字class 用的少
protocol OnlyForClass : class, CustomStringConvertible, CustomPlaygroundDisplayConvertible {
}
class MyText : OnlyForClass {
var description: String {
return "aaa"
}
var playgroundDescription: Any {
return "bbbb"
}
}
//报错,只能由class来继承
//struct : MyStruct : OnlyForClass
//{
//
//}
//协议组合 协议1 & 协议2 & 协议3
protocol Ageable {
var age : Int {get}
}
protocol Nameable {
var name : String { get }
}
struct StudentT : Ageable,Nameable {
var age : Int
var name : String
}
struct TeacherT : Ageable,Nameable {
var age : Int
var name : String
var title : String
}
func wish(someone : Ageable & Nameable) {
print("祝",someone.name,someone.age,"岁生日快乐!")
}
let studentt1 = StudentT(age: 10, name: "Tom")
let teachert1 = TeacherT(age: 30, name: "Bob", title: "Professor")
wish(someone: studentt1)
wish(someone: teachert1)
//没有很严格的意义,灵活性强,拆小功能,大的功能用小的功能组合
//协议的检查和转换 使用is和as类型操作符来检查协议遵从与否,或转换成特定的协议
protocol Slogan {
var desc: String { get }
}
protocol Coder : Slogan {
var name:String { get }
}
struct JavaCode : Coder {
var name: String
var desc: String {
return "我会Java我流弊"
}
}
struct JScoder : Coder {
var name: String
var desc: String {
return "我会JS我很潮"
}
}
struct NewBie {
var name : String
}
let java1 = JavaCode(name: "小牧")
let js1 = JScoder(name: "小可")
let newbie1 = NewBie(name: "小波")
let coders = [java1,js1,newbie1] as [Any]
for coder in coders {
if let coder = coder as? Coder {
print(coder.name,coder.desc)
}else {
print("你不是一个程序员")
}
if let newbie = coder as? NewBie {
print("你是菜鸟~",newbie.name)
}
}
Demo拉取地址:
https://gitee.com/xgkp/swiftBasicProtocol.git
明天开始放假,最后一个工作日了,回顾一年写的代码,还是有优化空间的,留作来年小尾巴~~~~
网友评论