• 扩展(分类)

类似于Objective-C中的分类功能

     即:在现有的一个类型(类类型、结构体、枚举)的基础上添加功能(方法)

     这个现有的类,可以是自定义的,也可以是其他框架中的(甚至没有源代码的)

     提供了一定的“逆向开发”的能力

格式:

     extension 现有类型 {

          //添加的功能

     }

可添加的功能:

     a. 添加行为属性、类行为属性(静态行为属性)、静态存储属性

     b. 添加各种方法:实例方法、类方法(静态方法)、便捷构造方法、下标方法等

     c. 添加新的嵌套类型

     d. 添加需要遵循的协议

     其中:类属性、类方法是类类型的,二静态   

不能添加的功能:

     a. 对象的存储属性(类存储属性(静态属性)可以)

     b. 不能重写方法,但可以重载

     c. 不能添加重名行为属性

意义:

     逆向开发

     复杂类型分模块开发

     ...

如结构体:

    extension Double {
       
static var pi1 = 3.14  //静态存储属性
        var pi2:Double { //行为方法
            return 3.14
        }
       
static var pi3:Double { //静态行为属性
            return 3.14
        }
       
func print1() { //实例方法
            print(self.pi2)
        }
       
static func print2() { //静态方法
            print(self.pi3)
        }
    }
   
var d1:Double = Double()
   
print(Double.pi1)
   
print(d1.pi2)
   
print(Double.pi3)
   
d1.print1()

    Double.print2()

如类类型:

    class A {
       
var names:[AnyObject] = [AnyObject]()
    }
   
extension A {
       
static var pi1 = 3.14 //静态存储属性
        var pi2:Double { //行为方法
            return 3.14
        }
       
class var pi3:Double { //类行为属性
            return 3.14
        }
       
func print1() { //实例方法
            print(self.pi2)
        }
       
class func print2() { //类方法
            print(self.pi3)
        }
       
//便捷构造方法
        convenience init(value:AnyObject, number:Int) {
           
self.init()
           
for var i=0; i                self.names.append(value)
            }
        }
       
//下标脚本方法
        subscript(index:Int)->AnyObject {
           
get {
               
return self.names[index]
            }
           
set {
               
self.names[index] = newValue
            }
        }
    }
   
var a1:A = A(value: "hello", number: 5)
   
for var i=0;i<5;i++ {
       
print(a1[i])
    }
   
print(A.pi1)
   
print(a1.pi2)
   
print(A.pi3)
   
a1.print1()

    A.print2()


  • 协议

协议规定了用来实现某些特定功能所需要的方法及属性

     类类型、结构体、枚举都可以遵循协议,即获得协议中规定接口并实现这些接口

     即:面向接口编程

协议定义格式:

     protocol 协议名称 { 协议体 }

     protocol 协议名称:协议1, 协议2  { 协议体 }

     协议还可以继承其他协议,且可以使多继承的

类类型特定协议格式:

     @objc protocol 协议名称 { 协议体 }

     protocol 协议名称: class { 协议体 }

     遵循协议的类型在实现的属性和方法前前需要 @objc 修饰

类型遵循协议:

     class 类名 : 协议名1, 协议名2 { }

     struct/enum 名字: 协议名1, 协议名2 { }

     类型可以遵循多个协议(只能有一个父类)

协议中的方法:

     协议中添加一系列相关方法的接口,并在遵循类型中给出实现

     可以是对象方法,也可以是类方法(用static修饰)

     在@objc修饰的协议中,可以使用optional修饰方法/属性

          在遵循类型中可以选择是否给出实现,否则必须实现

     如:

    @objc protocol AProtocol {
       
func sayHello()->String
       
static func sayHello()->String

    }

    class A : AProtocol {
       
@objc func sayHello()->String {
           
return "hello"
        }
       
@objc class func sayHello()->String {
           
return "HELLO"
        }

    }

协议中的属性:

     只能用var描述属性,遵循协议的类型实现属性时不能修改类型及标示符

     协议中声明的属性不能赋初值

     可以是 实例属性 也可以是 类属性(用static修饰)

     属性后{get} 表示 该属性在实现时可以是var也可以是let

     属性后{get set } 表示 该属性在显示时只能是var不能是let

     如:

    protocol CarProtocol {
       
var brandName:String { get set }    //品牌
        var modelName:String { get set }    //车型

        var price:Double { get set }        //价格

    }

    protocol HouseProtocol {
       
var houseName:String { get set }    //小区名
        var houseSize:Double { get set }    //平米大小
        var houseUnitPrice:Double { get set } //楼房单价

    }

    protocol MarryProtocol: CarProtocol, HouseProtocol {
       
static var isMarrayed:Bool { get set }
       
var marrayYear:Int { get }

    }

    class Person:MarryProtocol {
       
//CarProtocol
        var brandName:String = ""
       
var modelName:String = ""

        var price:Double = 0.0

        //HouseProtocol
        var houseName:String = ""
       
var houseSize:Double = 0.0

        var houseUnitPrice:Double = 0.0

        //MarrayProtocol
        static var isMarrayed:Bool = false
       
var marrayYear:Int {
           
get {
               
return 1
            }
        }

    }

协议中声明构造方法

     在协议中可以声明构造方法(包括便捷构造、可失败构造)

     遵循协议的类,在实现构造方法时,需要使用 required 关键字修饰

          其意义:该类的子类,需要重写这个协议声明的构造方法

          遵循协议的类,使用final修饰时,可以不适用required修饰构造方法

协议作为类型

     protocol<协议1,协议2,...>

     如:

    protocol AProtocol {
       
static var name:String { get set }
    }
   
protocol BProtocol {
       
var age:Int { get set }
    }
   
struct AStruct : AProtocol, BProtocol {
       
static var name:String = "AAA"
       
var age:Int = 111
    }
   
struct BStruct : AProtocol, BProtocol {
       
static var name:String = "BBB"
       
var age:Int = 222
    }
   
var p1:protocol<AProtocol, BProtocol> = AStruct()

    var p2:protocol<AProtocol, BProtocol> = BStruct()

协议的应用场合:

     一定程度上实现了多继承的功能

     常见的设计模式中,如代理设计模式

     现有类实现扩展时,可以子扩展中遵循协议