类是对象的模板
- 类中包含 属性 和 方法
- 属性和方法都是类的组成部分,属性是变量,方法是函数
- 方法中的代码可以利用self关键字访问类的属性,self引用当前运行改代码的对象
<pre>
<code>
`
class Car
{
var name = "拖拉机"
var speed = "50km/s"
func description() -> String
{
return "name->(self.name),speed->(self.speed)"
}
}
let car1 = Car()
print(car1.description())
`
</code>
</pre>
继承
- 当一个类继承另一个类(父类)时,它会包含父类所有的函数和属性
- 在Swift和Objective-C中,一个类只能有一个父类
- 从其他类继承而来的类可以重写父类中的函数,这就是说,可以创建一些子类,这些子类继承父类的大部分属性和方法,但可以有自己专属的属性和方法
- 要重写一个函数,要在子类中重新声明它,并添加关键字override,让编译器知道你不是在无意中创建了一个与父类中某个方法同名的方法
- 在一个被重写的函数中,经常需要回调该函数在父类中的版本,可以通过super关键字实现
<pre>
<code>
`
class Taxi : Car
{
var color = "red"
override func description() -> String
{
super.description()
return super.description() + ",color->\(color)"
}
}
let taxi1 = Taxi()
print(taxi1.description())
`
</code>
</pre>
初始化与反初始化
- 在Swift中创建新对象是,会调用一个被称为其初始化器的特殊方法,初始化器是用来为对象设定初始状态的方法
- 除了初始化器之外,还有个反初始化器,可以在对象消失时运行其中的代码,此方法在对象的retaincount降到0时运行,就在要将该对象从内存中清除时调用,要想在对象永远消失之前进行一些必要的清理工作,这是最后一个机会
- 初始化器还可以返回nil。当初始化器不能成功的构造一个函数时,这一点很有用。
- 要创建一个可以返回nil的初始化器(也可以称为失败的初始化器),就在init关键字的后面放上一个?并在初始化器确定它不能成功地构造该对象时返回nil
<pre>
<code>
`
class Person
{
//主初始化器
init()
{
print("a new person created by init!")
}
//快速初始化器
convenience init(name:String)
{
self.init()
print("a new person created by convenience init!")
}
//反初始化器
deinit
{
print("a person went way")
}
}
var person1 : Person?
person1 = Person()
person1 = nil
person1 = Person(name: "果啤")
</code> </pre> ![屏幕快照 2016-05-18 下午6.20.31.png](https://img.haomeiwen.com/i1650037/388b21702a030e1b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <pre> <code>
class Dog
{
init()//初始化器
{
print("a new dog created")
}
convenience init?(isMale:Bool)//失败的初始化器
{
self.init()
if isMale == true
{
print("I dont like male dog")
return nil
}
else
{
print("a new female dog created")
}
}
deinit
{
print("a dog went away")
}
}
let dog1 = Dog(isMale: true)
let dog2 = Dog(isMale: false)
`
</code>
</pre>
属性
- 类将其数据存储在属性中,任何添加到类中的属性都是可以访问的
- 属性是存储在对象中的一个简单值,在Swift中,它称为存储属性。但是,利用属性还能创建一些属性 ,利用代码来计算他们的取值,这些属性称为计算属性。计算属性从外部看,是一个普通属性,但从内部来说,它实际上是一个函数在需要时计算其值 。计算属性在定义时需要提供一个get部分(用来读取),还可视需要提供一个set部分(用来设置)
- 在使用属性时,经常希望在一个属性发生变化时运行某些代码。Swift属性允许向属性添加观察器,可以在一个属性值发生变化之前或者发生变化之后运行。属性观察器包含willSet和didSet代码块。willSet获得的是一个将要设定的属性值,didSet获得的是旧值。
- 我们还可以让属性变成惰性的,惰性属性就是直到首次访问时才会设定的属性。类的某些属性的设置需要耗费大量时间,利用惰性属性可以将这些工作推迟到将来真正需要时完成。为将一个属性定义为惰性的,可以在它的前面使用lazy关键字,这个属性将一直等到代码中实际用到它时才会使用
<pre>
<code>
`
class Square
{
var length : Double = 0
var circumference : Double
{
get
{
return length * 4
}
set
{
length = 5555
}
}
var area : Double = 0
{
willSet(newValue)
{
print("the new area will be \(newValue)")
}
didSet(oldValue)
{
print("the old area was \(oldValue)")
}
}
}
let square1 = Square()
square1.length = 3
print(square1.circumference)
square1.circumference = 15
print(square1.length)
square1.area = 16
</code> </pre> ![屏幕快照 2016-05-18 下午6.30.12.png](https://img.haomeiwen.com/i1650037/81ee5def4be64c0b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) <code> <pre>
class CostLittleTime
{
var time : Double
init(time:Double)
{
self.time = time
print("CostLittleTime->\(self.time)")
}
}
class CostMuchTime
{
var time : Double
init(time:Double)
{
self.time = time
print("CostMuchTime->\(self.time)")
}
}
class HasOneLazyProperty
{
var costLittleTime = CostLittleTime(time:2)
lazy var costMuchTime = CostMuchTime(time: 12345678)
init()
{
print("a new HasOneLazyProperty created!")
}
}
let hasOneLazyProperty1 = HasOneLazyProperty()
print(hasOneLazyProperty1.costMuchTime.time)
`
</code>
</pre>
协议
- 协议可以看做是一个类的需求清单。定义协议,就是创建一个属性和方法的清单。类可以声明它们拥有这些属性和方法
- 协议看起来与类非常相似,只是没有提供任何实际的代码,只是定义了存在哪些种类的属性和函数,以及如何访问它们
- 有了协议,就可以创建遵守协议的类。当一个类遵守一个协议时,就是向编译器做出了承诺:它实现了这个协议中列出的所有属性和方法。除此之外,它还可以有其他属性或方法,可以遵守多个协议。
- 使用协议的好处是,可以利用Swift的类型体系来引用任何遵守某一给定协议的对象。这一点非常重要,因为当你表明自己只关注一个对象是否遵守协议时,这个类的的具体类型是无关紧要的。
- 请记住:一个协议所做的全部工作就是指定一个类能够做些什么,至于怎么做则由类自己决定
<pre>
<code>
`
protocol Blinking//描述任何能够闪烁的对象的协议
{
var isBlinking : Bool { get }//是否在闪烁 只读
var blinkingSpeed : Double { get set }//闪烁频率 读&写
func startBlinking(blinkingSpeed:Double) -> Void //具体内容由实现者决定
}
class Light: Blinking
{
var isBlinking: Bool = false
var blinkingSpeed: Double = 0
func startBlinking(blinkingSpeed: Double)
{
isBlinking = true
self.blinkingSpeed = blinkingSpeed
print("i am blinking and speed is (self.blinkingSpeed)")
}
}
var aThingCanBlink : Blinking?
aThingCanBlink = Light()
print("aThingCanBlink?.isBlinking->(aThingCanBlink?.isBlinking)")
print("aThingCanBlink?.blinkingSpeed->(aThingCanBlink?.blinkingSpeed)")
aThingCanBlink?.startBlinking(250)
print("aThingCanBlink?.isBlinking->(aThingCanBlink?.isBlinking)")
print("aThingCanBlink?.blinkingSpeed->(aThingCanBlink?.blinkingSpeed)")
`
</code>
</pre>
扩展
- 在Swift中,可以扩展已有类型,并且增加更多方法和计算属性。这一点在以下两种情况下非常有用
- 正在使用别人编写的一个类型,希望向其中增加功能,但不能访问其源代码,或者不想为它花费太多时间
- 正在使用自己编写的一个类型,但希望将其功能分划到不同部分,以提高可读性
- 在Swift中,可以扩展任意类型,也就是说,可以扩展自己编写的类,可以扩展内置类型,比如Int或者String
- 要创建一个扩展需要使用Extension关键字
- 一旦扩展了一个类型,就可以调用已经增加的函数和属性,注意:在扩展一个类型时,在扩展中定义的函数和属性会被增加到该类型的每一个实例中
- 在扩展中只能增加计算属性,不能增加存储属性
- 可以利用扩展是一个类型遵守一个协议
<pre>
<code>
`
extension Double
{
var doubled : Double
{
return self * 2
}
func half() -> Double
{
return self/2
}
}
extension Double : Blinking
{
var isBlinking : Bool
{
return false
}
var blinkingSpeed : Double
{
get
{
return self
}
set
{
// do nothing
}
}
func startBlinking(blinkingSpeed: Double)
{
print("the double number is running at speed- >(blinkingSpeed)")
}
}
print(33.doubled)
print(33.half())
print(22.0.isBlinking)
print(22.0.blinkingSpeed)
55.0.startBlinking(55.0)
`
</code>
</pre>
本文部分引用自 图灵社区设计丛书《Swift与Cocoa框架开发》
网友评论