温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

协议

发布时间:2020-07-10 09:41:52 来源:网络 阅读:288 作者:hehemmm 栏目:开发技术

        如果类的所有方法都是抽象的,在Swift和Object-C中称为协议,在Java语言中称为接口,在C++中称为纯虚类;只有方法的定义没有方法的具体实现,所在的类叫抽象类


        协议不能被实例化


        Swift和Object-C中实现抽象类的过程称为遵守协议


一、声明和遵守协议

        类、结构体和枚举类型可以声明与遵守某个协议,并提供该协议所需要的属性和方法

        协议定义的语法如下:

            protocol 协议名 {

                //内容

}

            在声明遵守协议时,格式如下:

             类型  类型名:协议1,协议2 {

                    //遵守协议内容

}

            类型包括类、结构体和枚举,冒号后面是遵守的协议,如果有多个协议,协议之间用逗号隔开

            协议可以要求其遵守者提供实例属性,静态属性,实例方法和静态方法的实现,


二、协议方法


         协议可以要求其遵守者实现某些指定方法,包括实例方法和静态方法,这些方法在协议中被定义,协议方法和普通方法类似,但不支持边长参数和默认值参数,也不需要大括号和方法体


        1、实例协议方法

           

            protocol Figure {
                func onDraw()
}
             class Rectangle:Figure {
                    func onDraw(){
                        println("绘制矩形")
}
}
                class Circle:Figure {
                    func onDraw(){
                        println("绘制圆形")
}
}

        2、静态协议方法


            在协议中定义静态方法与在类中定义静态方法一样,方法前需要添加class关键字,在遵守该协议的时候,遵守者静态方法前加class或者static,与遵守者类型有有关系,如果是类,关键字就是class,如果是结构体或枚举,关键字就是static.

            protocol Account {
                    class func interestBy(amount:Double)->Double
}
            class ClassImp:Account {
                    class func interestBy(amount:Double)->Double {
                    return 0.668 * amount
}
}
            class StructImp:Account {
                            static func interestBy(){
                                      return 0.668 * amount   
    }        
}

        3、变异方法

            在结构体和枚举类型中可以定义变异方法,而在类中没有这种方法,原因是结构体和枚举中的属性是不可修改,通过定义变异方法,可以修改这些属性,而类是引用类型,不需要变种方法就可以修改自己的属性;

            在协议定义变种方法时,方法前要加上mutating关键字,类、结构体和枚举都可以实现变异方法,类实现变异方法时,前面不需要加mutating关键字,结构体和枚举在实现变异方法时,前面需要加mutating关键字

            protocol Editable {
                mutating func edit()
}
            class ClassImp:Editable{
                var name = "ClassImp"    
                func edit(){
                        println("编辑ClassImp...")
                        self.name = "编辑ClassImp"                    
    }
}
            struct StructImp:Editable {
                    var name = "StructImp"
                mutating func edit(){
                        println("编辑StructImp")
                        self.name = "编辑StructImp"
}
}

       

     struct Enum:Editable {
                    case Monday
                    case Tuesday
                    case Wednesday
                    case Thursday
                    case Friday
                    mutating func edit(){
                        self = .Friday
        }
}


            4、实例协议属性


                协议可以要求其遵守者实现某些指定属性,包括实例属性和静态属性,在具体定义的时候,每一种属性都可以有只读和读写之分


                对于遵守者而言,实例属性时市场灵活的,无论是存储属性还是计算属性,只要能通过协议属性的要求,就可以通过编译,甚至是协议中定义了只读属性,而遵守者提供了对该属性的读写,这也是被允许的,因为遵守者通过了协议的只读属性要求,协议只规定了必须要做的事情,但没有规定不能做的事情;


             protocol Person {
                    var firstName:String{get set}
                    var lastName:String {get set}
                    var fullName:String{get}
}
            class Employee:Person {
                    var no:Int = 0
                    var job:String?
                    var salary:Double = 0
                    
                    var firstName:String = "Tony"
                    var lastName:String = "zhang"
                    var fullName:String {
                            get {
                                return "\(firstName)\(lastName))"
}
                            set(newFullName){
                            var name = newFullName.componentsSeperatedByString(".")
                            self.firstName=name[0]
                            self.lastName=name[1]
                    }
            }
}

三、协议属性

        在协议中定义静态属性与在协议中定义静态属性类型,属性前面要加class关键字还是static,与遵守者类型有关系,如果是类,关键字是class,如果是结构体和枚举,关键字是static

            protocol Account {
                class var interestRate:Double {get}
                class func interestBy(amount:Double)->Double
}
            class ClassImp:Account{
                class var interestRate:Double {
                        return 0.668
}
                class func interestBy(amount:Double)->Double{
                        return ClassImp.interestRate * amount
}
}
                 struct StructImp:Account {
                        static var interestRate:Double = 0.668
                        static func interestBy(amount:Double)->Double {
                                return StructImp.interestRate * amount
}
}

四、把协议作为类型使用

            虽然协议没有具体的实现代码,不能被实例化,但它的存在是为了规范其遵守者而设计的,它是面向接口编程必不可少的机制,面向接口编程的系统的定义与实现应该分离,协议作为数据类型暴露给使用者,使其不用关心具体的实现细节,从而提供系统的扩展性和复用性;

            在Swift中,协议作为数据类型使用,它可以出现在任意允许数据类型出现的地方:

            protocol Person {
                var firstName:String{get set}
                var lastName:String {get set}
                var fullName:String{get}
                fun description()->String 
}
           class Student:Person {
                    var school:String
                    var firstName:String
                    var lastName:String
                    var fullName:String {
                            return self.firstName + self.lastName
}
                    func description()->String {
                        return self.firstName+self.lastName+self.school
}
                    init(firstName:String,lastName:String,school:String){
                        self.firstName = firstName
                        self.lastName = lastName
                        self.schooll = school
}
}


五、协议的继承

            一个协议继承就像是类继承一样:

            

           protocol Person {
                var firstName:String{get set}
                var lastName:String {get set}
                var fullName:String{get}
                fun description()->String 
}
                        protocol Student:Person {
                                    var school:String
}
                        class Graduate:Student{
                                    
}

六、协议的合成

        多个协议可以临时合并成一个整体,作为一个类型使用,首先要有一个类型在声明时遵守多个协议

        

        protocol Ship {
                var displacement:Double {get set}
}
        protocol Weapon {
                 var gunNumber{get set}
}
        class WarShip:Ship,Weapon{
                    var displacement = 100000.00
                    var gunNumber = 10
}
        func showWarResource(resource:protocol<Ship,Weapon>){
                    println("\(resource.displacement):\(resource.gunNumber)")
}
    let ship = WarShip()
    showWarResource(ship)


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI