Swift 面向对象解析(一)
面向对象总体概括:
Swift 不仅能够面向过程编程,也能够面向对象编程(OOP)。面向对象其实就是“以对象为核心”,把我们的客观世界想着是由一个个对象组成的,面向对象编程则为对象提供了属性和方法,属性就是为了描述对象的一些状态,方法则是告诉你对象该做什么。面向对象和核心就是“类”和“对象”!在我刚接触编程的时候,其实我也很容易把这东西混淆了,你要也是刚接触编程,能帮到你的,我觉得反而是时间。你要实在是有点难理解,就别去钻牛角尖,也许明天因为某个东西你就会恍然大悟。超喜欢那种感觉!
面向对象的三大特性: 继承 多态 封装 (封装和继承好理解,多态我在前面的博客中有提过,不理解可以往前面翻翻去看一下)。
Swift 面向对象编程的有五个单元: 枚举 结构体 类 扩展 协议
从整体的一个功能上看Swift的 枚举、结构体、类 三者具有完全平等的地位。(在后面我们会对这三者进行一个区分的)其他的面向对象编程的语言中都蛀牙提供了类一种单元,而Swift则有三种,大家想想,OC、Java等语言是面向对象编程的,Swift 是面向对象和过程都可以,Swift 是一门全新的语言,它才面世几年,而OC都快三十年了。所以Swift不简单,要是Swift刚出来那时候有人写出一个 println("Hello World")(2.0之前的写法) 就觉得它很简单,你真的就错了。Swift 不简单,你说简单估计是因为你也只研究到 print("Hello World"),哈哈......
在Swift中,枚举和结构体是值类型的,类是引用类型。值类型和引用类型的区别,我们后面说,先知道这一点。
在Swift的类、结构体、枚举中都可以定义(属性、方法、下标、构造体、嵌套类型),下面我们一个一个的用我小小的认识说一下它们,我也会给大家一些我看到的很不错的博客链接,方便大家更好的掌握,理解Swift。
一:枚举
Swift枚举是用来管理一组值的,当然也是有限的。比如一年四季你可以用枚举来管理,写个季节枚举,里面的值就是(春夏秋冬),还有性别(男女),再到我们的项目中比如经常看到的在即时通讯里面的消息类型(文字,图片,语音,系统消息)等等。比如下面的例子:
给大家看看我们在OC中是怎么定义枚举的,大家对比着理解:
/**
发送的消息类型
*/
enum ZxMessageType: Int { case MessageTypeUnknown = 0 // 未知
case MessageTypeSystem // 系统
case MessageTypeText // 文字
case MessageTypeImage // 图片
case MessageTypeVoice // 语音
case MessageTypeVideo // 视频
case MessageTypeFile // 文件
case MessageTypeLocation // 位置
case MessageTypeShake // 抖动 }
// OC 枚举
/**
* 消息类型
*/
typedef NS_ENUM(NSInteger, TLMessageType){ MessageTypeUnknown, // 未知
MessageTypeSystem, // 系统
MessageTypeText, // 文字
MessageTypeImage, // 图片
MessageTypeVoice, // 语音
MessageTypeVideo, // 视频
MessageTypeFile, // 文件
MessageTypeLocation, // 位置
MessageTypeShake, // 抖动 };
顺便给大家提一下,上面这两种方式,是我自己的习惯,其实按照我们最开始学的时候的方式去定义没问题,只是在官方的定义中,OC和Swift都是上面例子的方式写枚举,这样写也有好处,有同行分析过了,链接这里。
Swift枚举和 C,OC 枚举的区别: Swift的枚举成员不会被分配一个默认的整数值,它的枚举名本身就是一个枚举实例和整数值之间可没有任何的关系。
Swift的知识点还有:枚举值和Switch语句 原始值 关联值 等几个方面,但我就不说了,说了也不会有前辈们总结的详细,我把知识点链接给大家,里面的内容足够掌握 Swift的枚举了!
二:类和结构体
把这两个放在一起,纯粹是因为这两个太像了,我们先把区别罗列出来,剩下的两者都一样。
1: 结构体是值类型,类是引用类型。
2: 结构体不支持继承,不支持类型转换。(值类型原因)
3: 结构体不支持定义析构器。 (后面提析构器的时候说)
插入说个问题: 实例 和 对象 的问题,在以前的OC中,对象就是实例,实例就是对象。但在Swift 中,以前记得看书的时候说是有 类 的实例才能叫做 对象,而 结构体 和 枚举 的实例只能叫做实例,不能叫做对象。我觉得应该是和它们之间的类型有关系,他们之间最主要的区别其实也都是围绕着 值类型和引用类型展开的。
看看类的定义:
class name: super class {
// code
// 构造器
// 属性
// 方法
// 下标
}
注意点:
1: 当我们自己不为结构体/类 提供构造器时,系统为结构体生成两个构造器,一个是无参数的构造器,一个初始化所有存储属性的构造器。如果希望用户定义的构造器与系统提供的构造器同时存在,则不能直接在类中定义构造器,可用扩展来添加。
2: Swift 的属性分为两类,存储属性 和 计算属性 ,存储属性类似于OC中的实例变量,它用来保存类型本身或者实例变量的状态数据。计算属性相当于OC中用setter和getter合成的 property 属性,它并不一定保存数据。
三:存储和计算属性
(一) 存储属性
Swift 定义存储属性的方法和定义它变量常量的方法相同,我们就不累赘。
存储属性可以分为 实例存储属性 类型存储属性 两类。这个可以参考OC的实例方法和类型方法,实例变量和类型变量一样的道理去理解。
注意点:
1 : 枚举不能定义 实例存储属性, 类和结构体可以。
2 : Swift 要求所有的存储属性都必须显式的制定初始值,要么你在定义的时候指定初始值,要么你在构造器里面指定初始值。
3 : 如果将存储属性的类型申明为可选类型,系统就可以将这些属性的初始值设置为 nil (大家一定注意,Swift的nil和OC的nil完全不一样,Swift的nil是一个确定的值,叫缺失值,而OC的nil是一个不指向任何类型的指针)。
比如定义的一个 model;
class ZxUser: NSObject {
var username:String = ""
var userID:String = ""
var nikename:String = ""
var avatarURL:String = ""
var motto:String = ""
var phoneNumber:String = ""
var pinyin:String = ""
var initial:String = ""
}
在存储属性里面,我们要注意的是这个,延迟存储属性,延迟存储属性是指在第一次调用时才会被计算初始值的属性,声明延迟存储属性需要使用 Lazy 修饰符。
我们OC里面常用到的懒加载就是延时存储属性,我们看一个具体的例子就明白了:比如我们懒加载这个 ZxMessageModel 类型的数组,写法如下:
lazy var dataArray: Array<ZxMessageModel> = {
// 弱引用防止循环引用写法
// [weak self] in
// [unowned self] in
// __weak typeof (self) Wself = self
let dataArray:Array = Array<ZxMessageModel>()
return dataArray
}()
至于懒加载为什么这样写,有什么好处,看下面的链接!
Swift 懒加载(lazy) 和 Objective-C 懒加载的区别
(二) 计算属性
计算属性只能定义成变量形式,也就只能用 var 修饰。
计算属性就是相当于我们 OC 和 JAVA中通过 setter 和 getter 合成的属性(property属性)是一样的。
我们在OC中经常会这样用一个 property 属性,在.h中声明了这个属性,在.m中我们写它的 set 或者 get 方法,然后在他们的 set 或者 get 方法里面做一些操作,看下面的这个例子:
// 依据不同的条件判断返回不同的值
var cellHeight:CGFloat{
get{
switch self.messageType! {
case ZxMessageType(rawValue:2)!:
return self.messageSize.height + 40 > 60 ? self.messageSize.height + 40 :60
case ZxMessageType(rawValue:3)!:
return self.messageSize.height + 20;
default:
break
}
return 0
}
}
// 依据不同的消息类型设置不同的 cellIndentify
var messageType:ZxMessageType?{ get{
return self.messageType
}
set {
switch messageType! {
case ZxMessageType(rawValue:2)!:
self.cellIndentify = "TextMessageCell"; case ZxMessageType(rawValue:3)!:
self.cellIndentify = "ImageMessageCell"; case ZxMessageType(rawValue:4)!:
self.cellIndentify = "VoiceMessageCell"; case ZxMessageType(rawValue:5)!:
self.cellIndentify = "SystemMessageCell";
default:
break
}
}
}
学习链接:
四:属性观察者
willSet(newValue): 被观察的属性即将被赋值之前自动调用该方法。
didSet(oldValue): 被观察的属性被赋值完成之后自动调用该方法。
上面的形参名是Swift隐式为它们提供的,你可以在方法中直接调用,扣上面字眼去理解它们的定义和使用;
var nameString = ""{ willSet{
print("set value")
}
didSet{
print("did set value")
}
}
五:方法
方法这里我们就说一点,这个感觉是很基础的了,函数方法,说多了也没意思。
使用static 或者 class 修饰的方法属于该类型的类方法,是可以使用该类型本身来调用。class 一般是在类里面修饰, static 一般用在结构体和枚举中修饰。
六:下标
所有的Swift 类型(结构体、枚举、类)都支持定义下标,下标可以作为访问对象,集合或者序列的简化方式。
Swift使用 subscript 关键字定义下标。
看下面这个例子就明白它的作用了:
struct TimesTable { let multiplier: Int
subscript(index: Int) ->Int {
return multiplier * index
}
} // 在另外的方法里面这样调用,看输出的结果
let threeTimesTable = TimesTable(multiplier: 3)
print("sixtimes three is \(threeTimesTable[6])")
// prints"six times three is 18"
七:可选链
Swit 的所有类型默认是不能接受nil值的,如果程序想让某种数据类型能够接受nil值,则要将这种数据类型包装成可选类型:
1:在原有类型的后面添加 ? ,这种可选类型必须强制解析才能获得被包装的值。
2:在原有类型的后面添加 ! ,这种可选类型可有Swift隐式的解析被包装的值。
其实你掌握了可选类型的使用,可选链就没什么难度了,下面具体用法下面链接讲的很清楚:
八:构造器
构造器用于完成实例的构造过程,这个过程包括为实例中的每个存储属性社会中初始值和执行必要的准备和初始化任务, 与OC的构造器不同,Swift的构造器无需显式的声明返回值的类型,也无需显式使用 return返回实例, Swift 的构造器构造出来的实例由系统隐式的返回。它的本质其实就是一个或者多个名为 init 的函数。
九:可能失败的构造器
有些时候,枚举,结构体,类的构造可能不能成功的返回该类型的实例,比如你传入的构造器参数数据无效等等,这时候就定义了"可能失败的构造器"。
可能失败的构造器使用 init? 或者 init!来进行定义,在这种构造我的执行体内返回使用 return nil 来表示构造失败,该构造器返回了一个nil(缺失值)。
Swift 不允许定义两个具有相同形式类别的构造器,即使一个是可能失败的构造器,一个是普通的构造器。
后序的关于面向对象没写完的,还在制造中,有错误的地方欢迎指正,也可以加我QQ。。一起讨论学习
Swift 面向对象解析(一)的更多相关文章
- Swift 面向对象解析(二)
接着上面一篇说的内容: 一 继承: 苹果继承与水果,苹果是水果的子类,则苹果是一种特殊的水果:这就是继承的关系,这个我们学OC的时候相信也都理解了,就不再描述定义了,下面的就叫继承: class ZX ...
- ios开发中的Swift面向对象
iOS在现代计算机语言中,面向对象是非常重要的特性,Swift语言也提供了面向对象的支持.而且在Swift语言中,不仅类具有面向对象特性,结构体和枚举也都具有面向对象特性. 1.Swift中的类和结构 ...
- Swift XML解析库 - SwiftyXMLParser
经过在CocoaPods中筛选以后,发这个这个比较好用,整理出来 如果有需要可以在Pods命令端输入: pod search xml 这样会搜索出很多相关Xml的第三方库 SwiftyXMLParse ...
- iOS - Swift 面向对象语法
1.面向对象 面向过程:面向过程编成将所要解决的问题按解决问题的步骤进行分析.如果是大问题,就分解成为多个不同的小问题,在程序里叫做划分成不同的模块.每一个解决的步骤可能是一行或者几行代码,也可能是一 ...
- Swift Json 解析错误
昨天在开发公司的ios程序时,遇见一个json解析的问题,并且是一个非常奇怪的问题. 因为原来的代码比较复杂,所以对代码进行了一些简化,具体代码如下: 服务器返回格式(PHP): array( arr ...
- Swift强制解析
IDE:Xcode Version7.3.1 Swift中"数据类型?"表示这是可选类型,即 某个常量或者变量可能是一个类型,也可能什么都没有,不确定它是否有值,也许会是nil. ...
- Swift Json解析与model互转
Json的解码与编码操作,这里使用swift自带的类JSONDecoder 和 JSONEncoder 1.基础处理 如果你的 JSON 数据结构和你使用的 Model 对象结构一致的话,那么解析过程 ...
- Swift面向对象基础(中)——Swift中的方法
学习来自<极客学院> 1.定义方法需要在类型(枚举,结构体,类)里定义,不能独立定义,独立定义的是函数 2.方法要么属于该类型本身,要么是该类型的一个实例 3.不能独立执行方法,执行方法必 ...
- Swift面向对象基础(上)——Swift中的类和结构体(上)
学习来自<极客学院> import Foundation //1.定义类和结构体 /* [修饰符]calss 类名{ 零到多个构造器 零到多个属性 零到多个方法 零到多个下标 } 修饰符可 ...
随机推荐
- CodeForces 622D Optimal Number Permutation
是一个简单构造题. 请观察公式: 绝对值里面的就是 |di-(n-i)|,即di与(n-i)的差值的绝对值. 事实上,对于任何n,我们都可以构造出来每一个i的di与(n-i)的差值为0. 换句话说,就 ...
- ListView与RadioButton组合——自定义单选列表
标签: radiobuttonlistviewandroidlayout 2013-09-10 11:13 19396人阅读 评论(8) 收藏 举报 分类: Android(19) 版权声明: ...
- Ubuntu Nginx安装
1.先更新ubuntu系统 更新命令 sudo apt-get update sudo apt-get upgrade 2 添加ubuntu nginx更新源镜像 cd /etc/apt/ sudo ...
- NSURLRequest POST方式请求服务器示例
http://lizhuang.iteye.com/blog/1833297 1. 准备阶段 NSString *urlString = [NSString stringWithFormat:@&q ...
- pho
PDO(PHP Data Object) 是PHP 5新出来的东西,在PHP 6都要出来的时候,PHP 6只默认使用PDO来处理数据库,将把所有的数据库扩展移到了PECL,那么默认就是没有了我们喜爱的 ...
- 解决KVM中鼠标不同步问题
VNCViewer中的鼠标走得总是比本地系统中的鼠标要慢,不同步,往往实体机中的鼠标都移出vnc窗口外边了,虚拟机中的鼠标指针还没移到需要点击的位置,操作起来很不方便. 起初的想法也是配置的问题,就按 ...
- c++ builder 2009如何生成独立运行exe(转)
参考资料:https://forums.codegear.com/thread.jspa?threadID=13559&tstart=703 查了很多网站资料,说得差不多,但是最后编译出来的还 ...
- cygwin的安装,vi的使用,gcc,g++的使用(转)
源:cygwin的安装,vi的使用,gcc,g++的使用 Gcc的Makefile简单使用
- SD卡初始化以及命令详解
SD卡是嵌入式设备中很常用的一种存储设备,体积小,容量大,通讯简单,电路简单所以受到很多设备厂商的欢迎,主要用来记录设备运行过程中的各种信息,以及程序的各种配置信息,很是方便,有这样几点是需要知道的 ...
- 超全!整理常用的iOS第三方资源
一:第三方插件 1:基于响应式编程思想的oc 地址:https://github.com/ReactiveCocoa/ReactiveCocoa 2:hud提示框 地址:https://github. ...