swift 学习(三)(面向对象基础)
面向对象的基本特征包括:封装,继承,多态
在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"
}
原始值可以是 String
,Character
,Int
,Float
,但是只有 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 学习(三)(面向对象基础)的更多相关文章
- java基础学习05(面向对象基础01)
面向对象基础01 1.理解面向对象的概念 2.掌握类与对象的概念3.掌握类的封装性4.掌握类构造方法的使用 实现的目标 1.类与对象的关系.定义.使用 2.对象的创建格式,可以创建多个对象3.对象的内 ...
- Java学习 · 初识 面向对象基础一
面向对象基础 1.1面向过程与面向对象的区别 面向过程和面向对象二者都是思考问题的方式,再简单的事物时,可以线性思考时使用面向过程,但当事物较为复杂时,只能使用面向对象设计.但二者并不是对立的,在解决 ...
- Python学习之面向对象基础
python的面向对象和以前学的c++,Java都是一般,大同小异,面向对象基础先谈谈类的构造,编写,属性和方法的可见性等等 1.定义类,创建和使用对象 #定义类 class Student(obje ...
- java基础学习05(面向对象基础02)
面向对象基础02 实现的目标 1.String类的使用2.掌握this关键字的使用3.掌握static关键字的使用4.了解内部类 String类 实例化String对象一个字符串就是一个String类 ...
- java基础学习05(面向对象基础01--类实例分析)
面向对象基础01(类实例分析) 实现的目标 1.如何分析一个类(类的基本分析思路) 分析的思路 1.根据要求写出类所包含的属性2.所有的属性都必须进行封装(private)3.封装之后的属性通过set ...
- Java基础学习(三)—面向对象(上)
一.理解面向对象 面向对象是一种思想,是基于面向过程而言的,就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节:这种思想是将数据作为第一位,而方法或者说是 ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习--微博的基础框架搭建
学习如何使用Swift写项目 一.搭建微博项目的主框架 1.1--搭建功能模块 1.2--在 AppDelegate 中的 didFinishLaunchingWithOptions 函数,设置启动控 ...
- Java开发学习(三)----Bean基础配置及其作用范围
一.bean基础配置 对于bean的基础配置如下 <bean id="" class=""/> 其中,bean标签的功能.使用方式以及id和clas ...
- PHP学习(三)----面向对象
首先,还是建立一个好的理解模型: 1.什么是面向对象? 面向对象分为两个部分,那就是:什么是对象和什么是面向? 什么是对象: 对象的出现就是为了用代码更好的绘制我们现有的世界.那到底什么是对象呢? 一 ...
随机推荐
- Remove Duplicates From Sorted Array
Remove Duplicates from Sorted Array LeetCode OJ Given a sorted array, remove the duplicates in place ...
- POJ1985Cow Marathon[树的直径]
Cow Marathon Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 5117 Accepted: 2492 Case ...
- AC日记——找第一个只出现一次的字符 openjudge 1.7 02
02:找第一个只出现一次的字符 总时间限制: 1000ms 内存限制: 65536kB 描述 给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符.如果没有,输出no. 输入 一个字符串 ...
- VS 代码Diff 之Beyone Compare
前提条件 机器已安装 beyone compared软件和 visual svn for vs 插件. 在VS中集成SVN,我推荐使用 visual svn扩展. visual svn 官网:http ...
- jsp前三章测试
(选择一项) A: B: C: D: 正确答案是 B ,B/S架构并不是C/S架构的替代品,有些程序例如大型的网络游戏一般使用的是C/S架构. (选择多项) A: B: C: D: 正确答案是 A,C ...
- Android驱动入门-LED--HAL硬件访问服务层②
硬件平台: FriendlyARM Tiny4412 Cortex-A9 操作系统: UBUNTU 14.04 LTS 时间:2016-09-21 16:58:56 为了避免访问冲突,则创建了硬件访 ...
- box-shadow 的一些使用
1.只有左侧有阴影 box-shadow: -10px 0px 3px 1px #aaaaaa;
- Nginx/Apache服务连接数梳理
统计连接数,使用netstat命令或ss命令都可以1)统计连接数(80端口)[root@wang ~]# netstat -nat|grep -i "80"|wc -l872 或者 ...
- 完整的社交app源码android+laravel
等想到写点什么的时候再写吧,其他看代码. https://github.com/huijimuhe/monolog-android https://github.com/huijimuhe/monol ...
- 用TypeScript开发Vue——如何通过vue实例化对象访问实际ViewModel对象
用TypeScript开发Vue--如何通过vue实例化对象访问实际ViewModel对象 背景 我个人很喜欢TypeScript也很喜欢Vue,但在两者共同使用的时候遇到一个问题. Vue的实例化对 ...