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的枚举了!

Swift 中的枚举,你应该了解的东西

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
            }
        }
    }

学习链接:

Swift 属性

Swift和Objective-C中的属性特性

四:属性观察者

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隐式的解析被包装的值。

其实你掌握了可选类型的使用,可选链就没什么难度了,下面具体用法下面链接讲的很清楚:

Swift 可选链

八:构造器

构造器用于完成实例的构造过程,这个过程包括为实例中的每个存储属性社会中初始值和执行必要的准备和初始化任务, 与OC的构造器不同,Swift的构造器无需显式的声明返回值的类型,也无需显式使用 return返回实例, Swift 的构造器构造出来的实例由系统隐式的返回。它的本质其实就是一个或者多个名为 init 的函数。

具体用法和构造器的坑这里有

九:可能失败的构造器

有些时候,枚举,结构体,类的构造可能不能成功的返回该类型的实例,比如你传入的构造器参数数据无效等等,这时候就定义了"可能失败的构造器"。

可能失败的构造器使用 init? 或者 init!来进行定义,在这种构造我的执行体内返回使用 return nil 来表示构造失败,该构造器返回了一个nil(缺失值)。

Swift 不允许定义两个具有相同形式类别的构造器,即使一个是可能失败的构造器,一个是普通的构造器。

后序的关于面向对象没写完的,还在制造中,有错误的地方欢迎指正,也可以加我QQ。。一起讨论学习

时间: 2024-12-11 13:29:46

Swift 面向对象解析(一)的相关文章

Swift 面向对象解析(二)

接着上面一篇说的内容: 一 继承: 苹果继承与水果,苹果是水果的子类,则苹果是一种特殊的水果:这就是继承的关系,这个我们学OC的时候相信也都理解了,就不再描述定义了,下面的就叫继承: class ZXMessageCell: UITableViewCell { // 自定义的cell继承与UITableviewCell } 继承了父类,你也就能使用父类的属性方法,这些我们学OC的时候也都清楚.看下面几点, 1:重写父类的方法 2:重写父类的属性 3:重写属性观察者    上面的 1 2 3 只要

数据结构(八) AOV网的关键路径(Swift面向对象版)

上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的,但是工期不是最优的.因为拓扑序列是一个串行序列,如果按照该序列执行项目,那么就是串行执行的.我们知道在一个项目中的一些子工程是可以并行来完成的,这也就类似我们的多线程.今天我们要解决的问题就是找出一个关键路径,是工期最优并保证工程的完成.什么是关键路径,我们在下方会进行详细介绍. 一.关键路径概述 在聊关键路

ios开发中的Swift面向对象

iOS在现代计算机语言中,面向对象是非常重要的特性,Swift语言也提供了面向对象的支持.而且在Swift语言中,不仅类具有面向对象特性,结构体和枚举也都具有面向对象特性. 1.Swift中的类和结构体 Swift中的类和结构体定义的语法也是非常相似的.我们可以使用class关键词定义类,下面我们定义一个Person类,分别包含年龄和姓名属性. import UIKit class JRPerson: NSObject {} 我们发现现在类的定义和之前OC定义有了很大的不同,对于之前的.m文件和

Swift面向对象的类型

1.类 2.结构体(struct) 3.枚举(enum) 在swift语言中通过类和结构体实现面向对象,在Swift语言中,枚举也具有面向对象的特性 示例和对象 在面向对象中,将类创建对象的过程称为实例化,因此将对象称为实例化,但是在swift中,枚举和结构体不能称为对象,因为结构体和枚举并不是彻底的面向对象类型,而是只包含了一些面向对象的特定,例如,在Swift中继承只发生在类上,结构体和枚举不能继承

Swift XML解析库 - SwiftyXMLParser

经过在CocoaPods中筛选以后,发这个这个比较好用,整理出来 如果有需要可以在Pods命令端输入: pod search xml 这样会搜索出很多相关Xml的第三方库 SwiftyXMLParser是在Swift下的一个xml解析第三方库,支持索引,支持keyValue形式访问, 环境和语言支持:iOS 8.0+ ,  Swift 2.0+ 使用: let urlStr = ApiUrl + "/" + xmlFile(newsType) Alamofire.request(.GE

Swift Json 解析错误

昨天在开发公司的ios程序时,遇见一个json解析的问题,并且是一个非常奇怪的问题. 因为原来的代码比较复杂,所以对代码进行了一些简化,具体代码如下: 服务器返回格式(PHP): array( array('title' => '新浪','address' => 'http://www.sina.com.cn'), array('title' => '网易','address' => 'http://www.163.com') ); 解析部分的代码如下: var jsonData

Swift面向对象基础(上)——Swift中的枚举

Swift中枚举 学习笔记来自<极客学院> 1 import Foundation 2 3 /**********1*Swift定义枚举的语法格式*************/ 4 /* 5 enum 枚举名 { 6 使用case关键字列出所有枚举值 7 枚举的其他成员 8 } 9 */ 10 //定义枚举 11 enum Season{ 12 case Spring 13 case Summer 14 case Fall 15 case Winter 16 } 17 //使用一个case列举所

Swift面向对象中类和对象的属性

Swift中类和对象的属性分为三种:储存属性,计算属性和类属性. import Foundation class Person { // 储存属性必须赋初值 var score1: Int = 20 var score2: Int = 50 // 延迟储存属性,需要时再去分配 lazy var dog: Dog = Dog() // 计算属性,不能赋初值,提供get和set方法, var sum: Int { get { return score1 + score2 } } // 类属性,只能是

数据结构(五) 普利姆与克鲁斯卡尔的最小生成树(Swift面向对象版)

上篇博客我们聊了图的物理存储结构邻接矩阵和邻接链表,然后在此基础上给出了图的深度优先搜索和广度优先搜索.本篇博客就在上一篇博客的基础上进行延伸,也是关于图的.今天博客中主要介绍两种算法,都是关于最小生成树的,一种是Prim算法,另一个是Kruskal算法.这两种算法是很经典的,也是图中比较重要的算法了. 今天博客会先聊一聊Prim算法是如何生成最小生成树的,然后给出具体步骤的示例图,最后给出具体的代码实现,并进行测试.当然Kruskal算法也是会给出具体的示例图,然后给出具体的代码和测试用例.当