面向对象的基本特征包括:封装,继承,多态

在swift中,类,结构,枚举都具有面向对象特性

但结构和枚举的实例不称为对象,因为结构和枚举不是彻底的面向对象类型,比如他们不能继承。

结构体

struct Point {
var x,y: Double
}
struct Size{
var width, height: Double
}
struct Rect {
var origin : Point
var size: Size
var area: Double {
return size.width * size.height
}
//结构,枚举中试图修改属性值得方法,计算属性都要加mutating
//当声明的是一个常量的时候,这些方法都不可调用
mutating func moveToTheRightBY(dx: Double){
x += dx
}
} var point = Point(x:0.0,y:0.0)
var size = Size(width: 640.0, height: 480.0)
var rect =Rect(origin: point, size: size)

  

// 访问权限 public private internal,默认是internal
class people{
// 存储属性 持有数据
var 存储实例属性 = ""
lazy var 惰性实例存储属性 = UIView()
// class let 类存储属性 = 11 不支持
static let 静态存储属性 = 22 // 属性观察者 不能用于惰性属性
var 属性观察者:Int = 0{
willSet(newValue){ }
didSet{ }
} // class + lazy + final 等同 static
// 计算属性 是方法的变种
class var 类计算属性: Int {
return 1
} class final var 类计算属性2: Int {
return 1
} static var 静态计算属性3:Int{
return 1
}
var 实例计算属性:Int{
set(newValue){ }
get{
return 1
}
} // 下标方法
subscript(number:Int)->String?{
get{ }
set(newValue){ }
} class func 方法(){}
class final func 方法2(){} static func 方法3(){} func 方法4(){}
}

  

lazy 只能修饰存储属性,必须自带默认值,且必须声明为变量,不能使用let,因为常量必须在实例构建时赋值。

  是一种将对象的创建或其它高负荷操作延迟到真正需要时才执行的机制。被修饰的字段只有在被调用时才会分配内存,并初始化。也因此,在懒加载属性被调用时,实例的其他非懒加载成员早已存在,所以懒加载属性可以用闭包直接赋值,从而自带逻辑处理。

lazy var players: String[] = {
var temporaryPlayers = String[]()
temporaryPlayers.append("Mike Buss")
return temporaryPlayers
}()

  

属性观察者 willSet,didSet用于观察存储属性值的变化,但不能用于lazy修饰的存储属性

class修饰符不可以用来声明存储属性,只能用于方法和计算属性。表示该成员属所有类的实例公有,作用类似java里的static

static修饰符可以用于存储属性,作用相当于class + final + lazy。静态成员同样是懒加载,且可以被子类继承,但子类调用该成员时,实际上和父类操作的是同一个变量,同一个函数。

class Father{
static var x = 2
}
class Son: Father{
} println(Father.x) //2
println(Son.x) //2
Son.x = 3
println(Father.x) //3
println(Son.x) //3

  

final修饰符的几点使用原则

  • final修饰符只能修饰类,表明该类不能被其他类继承,也就是它没资格当父类。
  • final修饰符也可以修饰类中的属性、方法和下标,但前提是该类并没有被final修饰过。
  • final不能修饰结构体和枚举。因为结构体和枚举只能遵循协议(protocol)。虽然协议也可以遵循其他协议,但是它并不能重写遵循的协议的任何成员

枚举

//C中的枚举为了提高可读性,便于维护,而swift中却强大很多
enum Day:Int {
case Monday = 1, Tuesday, Wednesday, Thursday,
Friday, Saturday, Sunday
}
var day = Day.Thursday
day = .Monday
let dayNumber = day.toRaw() //原形(行值) enum Direction {
case North, South, East, West
} //基于什么类型无关紧要,可以不写 let label = UILabel()
label.textAlignment = .Right enum TrainStatus {
case OnTime
case Delayed(Int) //关联值
init() {
self = OnTime
}
var description :String {
switch self {
case OnTime :return "准时到达"
case Delayed(let minutes): return "延误\(minutes)分钟"
}
}
}
var status = TrainStatus ()
println("列车已\(status.description )")
status = .Delayed(43)
println("列车已\(status.description )") class Train {
enum TrainStatus {
case OnTime, Delayed(Int) //关联值
init() {
self = OnTime
}
var description :String {
switch self {
case OnTime :return "准时到达"
case Delayed(let minutes): return "延误\(minutes)分钟"
}
}
}
var status = TrainStatus ()
}

  

// 枚举应用

// 实现布尔类型

enum myBool {
case myTrue
case myFalse
} extension myBool{
init(){
self = myBool.myFalse
}
} /// 可以用布尔值 字面量赋值
extension myBool:BooleanLiteralConvertible{
init( booleanLiteral value: Bool){
self = value ? .myTrue : .myFalse
}
}
var aaa:myBool = true
var bbb:myBool = true extension myBool:BooleanType{
var boolValue: Bool {
return self == .myTrue
}
} if aaa{
println(11)
} /// 可以用任何遵循BooleanType的类型初始化
extension myBool{
init<T : BooleanType>(_ value: T){
if value.boolValue{
self = .myTrue
}
else{
self = .myFalse
}
}
}
aaa == bbb
/// 比较
extension myBool:Comparable,Equatable{ } func <(lhs: myBool, rhs: myBool) -> Bool{
switch (lhs,rhs){
case (.myTrue,.myFalse):
return true
default:
return false
}
} if aaa < bbb{
println(222112)
}

  

// 枚举类中定义了两种条形码,一种是普通的条形码 UPCA ,存储四个 Int 值;
// 另一种是二维码 QRCode ,存储一个字符串的值: enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
} // 枚举的值可以有关联值,并不是说这里的枚举值就是函数或闭包,
// 在switch中可以提供相应的处理代码。
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP") switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
println("QR code: \(productCode).")
}
// prints "QR code: ABCDEFGHIJKLMNOP." // 如果我们要比较两个枚举变量,比如 code1 == code2 ,需要重载运算符 func ==(a:Barcode, b:Barcode) -> Bool {
switch(a) { case let .UPCA(a1,b1,c1,d1):
switch(b) {
case let .UPCA(a2,b2,c2,d2):
return (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
default:
return false
} case let .QRCode(a1):
switch(b) {
case let .QRCode(a2):
return a1 == a2
default:
return false
}
}
} enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
} var code1 = Barcode.UPCA(8, 85909, 51226, 3)
var code2 = Barcode.UPCA(8, 85909, 51226, 4) code1 == code2 // false

  

// 如果没有相关值是可以直接比较的:

enum Numbers: Int {
case One = 1, Two, Three, Four, Five
}
var possibleNum1 = Numbers.Three
var possibleNum2 = Numbers.Three
println(possibleNum1 == possibleNum2) // true

  

 

原始值 - Raw Values

我们可以给枚举类型的成员用默认值填充,比如下面这个例子,成员的类型为 Character :

enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}

  

原始值可以是 StringCharacterIntFloat,但是只有 Int 可以自增。使用 toRaw 可以访问该枚举成员的原始值:

ASCIIControlCharacter.Tab.rawValue  // rawValue = \t

也可以用 fromRaw 从原始值转换成枚举成员,注意返回的是 .Some ,因为不一定能转换成功:

var a = ASCIIControlCharacter(rawValue: "\t")
a?.rawValue // {Some "\t"}

遍历

我们可以通过 allValues 遍历枚举类型的所有成员:

enum ProductCategory : String {
case Washers = "washers", Dryers = "dryers", Toasters = "toasters" static let allValues = [Washers, Dryers, Toasters]
} for category in ProductCategory.allValues{
//Do something
}

  

用处

用好枚举类型可以有效的提高代码的可读性,比如我们在 prepareForSegue 中经常需要对 segue.segueIdentifier 进行比较,如果纯粹的进行字符串比较显得很生硬,不妨在外面套上一层枚举类型,像这样:

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if let identifier = SegueIdentifier.fromRaw(segue.identifier) {
switch identifier {
case .OtherScreenSegue1:
println("Going to other screen 1")
case .OtherScreenSegue2:
println("Going to other screen 2")
case .OtherScreenSegue3:
println("Going to other screen 3")
default:
println("Going somewhere else")
}
}
}

  

同理,用在 NSNotificationCenter 里。

enum WebQuest{

  case success(data:[String:AnyObject],block:()->())

  case fail(error:NSError,block:()->())

}

  

swift 学习(三)(面向对象基础)的更多相关文章

  1. java基础学习05(面向对象基础01)

    面向对象基础01 1.理解面向对象的概念 2.掌握类与对象的概念3.掌握类的封装性4.掌握类构造方法的使用 实现的目标 1.类与对象的关系.定义.使用 2.对象的创建格式,可以创建多个对象3.对象的内 ...

  2. Java学习 · 初识 面向对象基础一

    面向对象基础 1.1面向过程与面向对象的区别 面向过程和面向对象二者都是思考问题的方式,再简单的事物时,可以线性思考时使用面向过程,但当事物较为复杂时,只能使用面向对象设计.但二者并不是对立的,在解决 ...

  3. Python学习之面向对象基础

    python的面向对象和以前学的c++,Java都是一般,大同小异,面向对象基础先谈谈类的构造,编写,属性和方法的可见性等等 1.定义类,创建和使用对象 #定义类 class Student(obje ...

  4. java基础学习05(面向对象基础02)

    面向对象基础02 实现的目标 1.String类的使用2.掌握this关键字的使用3.掌握static关键字的使用4.了解内部类 String类 实例化String对象一个字符串就是一个String类 ...

  5. java基础学习05(面向对象基础01--类实例分析)

    面向对象基础01(类实例分析) 实现的目标 1.如何分析一个类(类的基本分析思路) 分析的思路 1.根据要求写出类所包含的属性2.所有的属性都必须进行封装(private)3.封装之后的属性通过set ...

  6. Java基础学习(三)—面向对象(上)

    一.理解面向对象       面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节:这种思想是将数据作为第一位,而方法或者说是 ...

  7. swift学习笔记1——基础部分

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  8. Swift学习--微博的基础框架搭建

    学习如何使用Swift写项目 一.搭建微博项目的主框架 1.1--搭建功能模块 1.2--在 AppDelegate 中的 didFinishLaunchingWithOptions 函数,设置启动控 ...

  9. Java开发学习(三)----Bean基础配置及其作用范围

    一.bean基础配置 对于bean的基础配置如下 <bean id="" class=""/> 其中,bean标签的功能.使用方式以及id和clas ...

  10. PHP学习(三)----面向对象

    首先,还是建立一个好的理解模型: 1.什么是面向对象? 面向对象分为两个部分,那就是:什么是对象和什么是面向? 什么是对象: 对象的出现就是为了用代码更好的绘制我们现有的世界.那到底什么是对象呢? 一 ...

随机推荐

  1. NOIP2015子串[序列DP]

    题目背景 无 题目描述 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重 叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个 ...

  2. NOI 2002 营业额统计 (splay or fhq treap)

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

  3. FragmentTransaction.replace() 你不知道的坑

    一.起源: 先看效果,在linearLayout中添加了4个Fragment,然后点击替换一次确替换了两个Fragment,引发了我的研究兴趣: 第一次启动                       ...

  4. jQuery学习之jQuery Ajax用法详解

    jQuery Ajax在web应用开发中很常用,它主要包括有ajax,get,post,load,getscript等等这几种常用无刷新操作方法,下面我来给各位同学介绍介绍. 我们先从最简单的方法看起 ...

  5. ASP.NET 中执行 URL 重写

    具体实现步骤(其中的一种实现方法): 一.下载相关的DLL(ActionlessForm.dll和UrlRewriter.dll) http://download.csdn.net/detail/yi ...

  6. 清北学堂2017NOIP冬令营入学测试P4749 C’s problem(c)

    P4746 C's problem(c) 时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描述 小C是一名数学家,由于它自制力比较差 ...

  7. ZooKeeper 笔记(2) 监听数据变化

    ZK中的每个节点都可以存储一些轻量级的数据,这些数据的变化会同步到集群中的其它机器.在应用中程序员可以添加watcher来监听这些数据的变化,watcher只会触发一次,所以触发过后想要继续监听,必须 ...

  8. 教你如何反编译Android安装文件apk来偷窥源代码

    本文章首发于浩瀚先森博客,地址:http://www.guohao1206.com/2016/08/23/970.html 1. 准备 - java环境 安装java并配置环境 => JAVA环 ...

  9. K-means算法及文本聚类实践

    K-Means是常用的聚类算法,与其他聚类算法相比,其时间复杂度低,聚类的效果也还不错,这里简单介绍一下k-means算法,下图是一个手写体数据集聚类的结果. 基本思想 k-means算法需要事先指定 ...

  10. Python2.2-原理之类型和运算

    此节来自于<Python学习手册第四版>第二部分 一.Python对象类型(第4章) 1. Python可以分解成模块.语句.表达式以及对象:1.程序由模块构成:2.模块包含语句:3.语句 ...