余晖落尽暮晚霞,黄昏迟暮远山寻
本站
当前位置:网站首页 > 编程知识 > 正文

Swift 面向对象解析(一)(swift 面向协议)

xiyangw 2022-12-03 12:06 30 浏览 0 评论

面向对象总体概括:

Swift 不仅能够面向过程编程,也能够面向对象编程(OOP)。面向对象其实就是“以对象为核心”,把我们的客观世界想着是由一个个对象组成的,面向对象编程则为对象提供了属性和方法,属性就是为了描述对象的一些状态,方法则是告诉你对象该做什么。面向对象和核心就是“类”和“对象”!在我刚接触编程的时候,其实我也很容易把这东西混淆了,你要也是刚接触编程,能帮到你的,我觉得反而是时间。你要实在是有点难理解,就别去钻牛角尖,也许明天因为某个东西你就会恍然大悟。超喜欢那种感觉!

Swift 面向对象解析(一)(swift 面向协议)

面向对象的三大特性: 继承 多态 封装 (封装和继承好理解,多态我在前面的博客中有提过,不理解可以往前面翻翻去看一下)。

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
    }

至于懒加载为什么这样写,有什么好处,看下面的链接!

(二) 计算属性

计算属性只能定义成变量形式,也就只能用 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。。一起讨论学习

相关推荐

前后端分离 Vue + NodeJS(Koa) + MongoDB实践

作者:前端藏经阁转发链接:https://www.yuque.com/xwifrr/gr8qaw/vr51p4写在前面闲来无事,试了一下Koa,第一次搞感觉还不错,这个项目比较基础但还是比较完整了,...

MongoDB 集群如何工作?

一、什么是“MongoDB”?“MongoDB”是一个开源文档数据库,也是领先的“NoSQL”数据库,分别用“C++”“编程语言”编写,使用带有“Schema”的各种类似JSON的文档,是也分别被认为...

三部搭建mongo,和mongo UI界面

三步搭建mongo,和mongoUI界面安装首先你需要先有一个docker的环境检查你的到docker版本docker--versionDockerversion18.03.1-ce,b...

Mongodb 高可用落地方案

此落地方案,用于实现高可用。复制集这里部署相关的复制集,用于实现MongoDB的高可用。介绍MongoDB复制集用于提供相关的数据副本,当发生硬件或者服务中断的时候,将会从副本中恢复数据,并进行自动...

一次线上事故,我顿悟了MongoDB的精髓

大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?让我们一起,一探究竟,继续学习MongoDB分片的理论与实践,...

IDEA中安装MongoDB插件-再也无要nosql manager for mongodb

大家都知道MongoDB数据库作为典型的非关系型数据库被广泛使用,但基于MongoDB的可视化管理工具-nosqlmanagerformongodb也被用的较多,但此软件收费,所以国内的破解一般...

数据库监控软件Lepus安装部署详解

Lepus安装部署一、软件介绍Lepus是一套开源的数据库监控平台,目前已经支持MySQL、Oracle、SQLServer、MongoDB、Redis等数据库的基本监控和告警(MySQL已经支持复...

YAPI:从0搭建API文档管理工具

背景最近在找一款API文档管理工具,之前有用过Swagger、APIManager、Confluence,现在用的还是Confluence。我个人一直不喜欢用Swagger,感觉“代码即文档”,让代...

Mac安装使用MongoDB

下载MongoDB包:https://www.mongodb.com/download-center解压mongodb包手动解压到/usr/local/mongodb文件夹配置Mac环境变量打开环境...

保证数据安全,不可不知道的MongoDB备份与恢复

大家在项目中如果使用MongoDB作为NOsql数据库进行存储,那一定涉及到数据的备份与恢复,下面给大家介绍下:MongoDB数据备份方法在MongoDB中我们使用mongodump命令来备...

MongoDB数据备份、还原脚本和定时任务脚本

备注:mongodump和mongorestore命令需要在MongoDB的安装目录bin下备份脚本备份格式/usr/local/mongodb/bin/mongodump -h ...

等保2.0测评:mongoDB数据库

一、MongoDB介绍MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产...

MongoDB入门实操《一》

什么是MongoDBMongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之...

Python安装PyMongo的方法详细介绍

欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练、PDF电子文档、面试集锦、学习资料等。前言本文主要给大家介绍的是关于安装PyMongo的...

第四篇:linux系统中mongodb的配置

建议使用普通用户进行以下操作。1、切换到普通用户odysee。2、准备mongodb安装包,自行去官网下载。3、解压安装包并重命名为mongodb4.04、配置mongodbcdmongod...

取消回复欢迎 发表评论: