美文网首页
Swift--Swift语言中的面向对象特性

Swift--Swift语言中的面向对象特性

作者: 优雅的步伐 | 来源:发表于2019-10-07 22:34 被阅读0次
  • Swift语言中的面向对象类型

  • 枚举

  • 结构体

  • 可选链

  • 访问限定

Swift语言中的面向对象类型

面向对象概念的基本特征
  • 封装性。封装性是尽可能隐藏对象的内部细节,对外形成一个边界,只保留有限的对外接口使之与外部发生联系。
  • 继承性。一些特殊类能够具有一般类的全部属性和方法,这称做特殊类对一般类的继承。例如客轮与轮船,客轮是特殊类,轮船是一般类。通常我们称一般类为父类(或基类),称特殊类为子类(或派生类)。
  • 多态性。对象的多态性是指在父类中定义的属性或方法被子类继承之后,可以使同一个属性或方法在父类及其各个子类中中具有不同的含义,这称为多态性。例如动物都有吃的方法,但是老鼠的吃法和猫的吃法是截然不同的。
Swift中的面向对象类型

在Swift语言中类、结构体(struct)和枚举(enum)都是面向对象的数据类型,具有面向对象的特征。而在其他语言中,结构体和枚举是完全没有面向对象特性的,Swift语言赋予了它们面向对象特征。

注意: Swift语言中只有类具有面向对象的三个特征,而结构体和枚举只具有封装性,结构体和枚举是不具有继承性和多态性的。

  • 在面向对象中类创建对象的过程称为“实例化”,实例化的结果称为“实例”,类的“实例”也称为“对象”。但是在 Swift中,结构体和枚举的实例一般不称为“对象”,这是因为结构体和枚举并不是彻底的面向对象类型,而只是包含了一些面向对象的特点。

  • 例如,在Swift中继承和多态只发生在类上,结构体和枚举不能继承。

枚举

在C和Objective-C中,枚举用来管理一组相关常量集合,通过使用枚举可以提高程序的可读性,使代码更清晰,更易于维护。
而在Swift中,枚举的作用已经不仅仅是定义一组常量、提高程序的可读性了,它还具有了面向对象特性
我们先来看Swift声明。Swift中也是使用enum关键词声明枚举类型,具体定义放在一对大括号内,枚举的语法格式如下:
enum 枚举名
{
枚举的定义
}

成员值

在Swift中,枚举的成员值默认情况下不是整数类型,以下代码是声明枚举示例:
enum WeekDays {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
}
也可以将多个成员值放在一行,用逗号隔开,如下所示:
enum WeekDays {
case Monday, Tuesday, Wednesday, Thursday, Friday
}

enum WeekDays {
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
}

//var day: WeekDays = WeekDays.Friday
var day =  WeekDays.Friday
day = WeekDays.Wednesday
day = .Monday //day经过前面的赋值之后,已经确定了它的数据类型,所以可以省略类型及枚举的名字,写成.成员

func writeGreeting(day: WeekDays) {
    switch day {
    case .Monday:
        print("星期一好啊")
    case .Tuesday:
           print("星期二好啊")
    case .Wednesday:
           print("星期三好啊")
    case .Thursday:
           print("星期四好啊")
    case .Friday:
           print("星期五好啊")
//    default:
//          print("星期五好啊!")
    }
}

writeGreeting(day: day)
writeGreeting(day: WeekDays.Friday)
writeGreeting(day: .Thursday)

注意:

1、使用枚举成员赋值时,我们可以采用完整的“枚举类型名.成员值”的形式,也可以省略枚举类型而采用“.成员值”的形式。
这种省略形式能够访问的前提是,Swift编译器能够根据上下文环境推断类型

2、在switch中使用枚举类型时,switch语句中的case必须全面包含枚举中的所有成员,不能多也不能少,包括使用default的情况下,default也表示某个枚举成员。在上面的示例中,default表示的是Friday枚举成员,在这种情况下,Friday枚举成员的case分支不能再出现了。

原始值

我们可以为枚举类型提供原始值(raw values)声明,这些原始值类型可以是: 字符、字符串、整数和浮点数等。
原始值枚举的语法格式如下:
enum 枚举名:数据类型
{
case 成员名 = 默认值
......
}
在“枚举名”后面跟“:”和“数据类型”就可以声明原始值枚举的类型,然后在定义case成员的时候需要提供默认值。

enum WeekDays2: Int {
    case Monday   = 0
    case Tuesday  = 1
    case Wednesday = 2
    case Thursday = 3
    case Friday = 4
}
当枚举类型为整数类型的时候,可以为第一个成员指定原始值,其他成员会自动累加,不用指定原始值,仅限于整数类型。如下:
enum WeekDays2: Int {
    case Monday   = 0, Tuesday, Wednesday, Thursday, Friday
}
枚举类型为String类型时,只指定第一个成员的原始值时,那其他成员的原始值就是它所在枚举中的成员值。如下:
enum WeekDays2: String {
    case Monday   = "A", Tuesday, Wednesday, Thursday, Friday
}
print(WeekDays2.Friday.rawValue) //输出:Friday,即为成员值
枚举类型为Double类型时,每个成员必须指定原始值,还必须和其他成员的原始值不能重复
enum WeekDays2: Double {
    case Monday   = 0.0, Tuesday = 1.0, Wednesday = 2.0, Thursday = 3.0, Friday = 4.0
}
通过成员值获得原始值
let friday = WeekDays2.Friday.rawValue
print("friday==", friday)//输出:friday== 4
通过原始值获得成员值
let thursday = WeekDays2(rawValue: 3)
print("thursday==", thursday)

通过枚举类型的构造函数,构造函数中有个参数rawValue,用原始值rawValue为3来构建一个枚举类型,得到的值就是原始值为3所对应的成员值thursday

完整代码:
enum WeekDays2: Int {
    case Monday   = 0, Tuesday, Wednesday, Thursday, Friday
}
print(WeekDays2.Friday.rawValue)//rawValue用来显示原始值
var day2 = WeekDays2.Friday
day2 = WeekDays2.Wednesday

func writeGreeting2(day2: WeekDays2) {
    switch day {
    case .Monday:
        print("星期一好!")
    case .Tuesday:
        print("星期一好!")
    case .Wednesday:
        print("星期一好!")
    case .Thursday:
        print("星期一好!")
    default:
         print("星期五好啊!")
    }
}
//通过成员值获得原始值
let friday = WeekDays2.Friday.rawValue
print("friday==", friday)//输出:friday== 4

//通过原始值获得成员值
let thursday = WeekDays2(rawValue: 3)
print("thursday==", thursday)

if (WeekDays2.Friday.rawValue == 4) {
    print("今天是星期五")
}

注意: 原始值很多情况下不需要的,之所以使用原始值,实际上Swift是为迎合程序员的心理上的需要,因为之前的语言使很多程序员都认为枚举类型是一个整数类型,而且很多情况下是把枚举类型拿来判断的,现在如果只是出于判断的目的,就不需要原始值,直接使用枚举的成员值就好了。

类和结构体定义

class 类名{
定义类的成员
}

struct 结构体名 {
定义结构体的成员
}

类图
image.png

结构体和类的区别:如果不考虑到面向对象的继承和多态的时候,结构体和类并没有什么区别,但如果考虑到未来的继承和多态,那一定要把类型声明成类的类型,而不是结构体。

//类和结构体
class Employee {
    var no: Int = 0
    var name: String = ""
    var job: String?
    var salary: Double = 0
    var dept: Department?
}

struct Department {
    var no: Int = 0
    var name: String = ""
    var employees: [Employee]?
}

var emp = Employee()
var department = Department()

可选链

可选链就是可选类型的具体的应用

可选链概念
image.png

注意: 1、加感叹号(!) 为强制拆包方式,也叫显示拆包方式,这种方式有个弊端,如果中间有个链条是为空的话,例如emp.dept为空的话,那么员工引用部门的这块就不会再往下走了,如果用感叹号(!)进行强制拆包的话就会出现异常,程序就会崩溃。我们在可选类型中学过,如果我们试图对一个空值进行强制拆包的话,就会出现异常,出现错误,程序就会崩溃。

2、问号(?)是一种比较温柔的方式,我们叫做可选链是允许为空值的,如果emp.dept为空的话,没有关系,最后返回的结果就是空值,只是不会往公司这一层级找,程序不会崩溃。

3、可选链的最后结果还是可选的,我们把问号的这种方式所形成的链条称为可选链

使用问号(?)和感叹号(!)
1、可选类型中的问号(?)

声明这个类型是可选类型,访问这种类型的变量或常量时要使用感叹号(!),下列代码是显示拆包:
let result1: Double? = 100 //声明可选类型
print(result1!) //显示拆包取值(强制拆包取值), 输出结果为100.0

2、可选类型中的感叹号(!)

声明这个类型是可选类型,但是访问这种类型的变量或常量时可以不使用感叹号,下列代码是隐式拆包:
let result2: Double? = 200 //声明可选类型
print(result2) //隐式拆包取值,输出结果为Optional(100.0)

3、可选链中的感叹号(!)

多个实例具有关联关系,当从一个实例引用另外实例的方法、属性和下标等成员时就会形成引用链,由于这个”链条“某些环节可能有值,也可能没有值,因此需要采用如下方式访问:
emp.dept!.comp!.name

4、可选链中的问号(?)

在可选链中使用感叹号(!)访问时,一旦”链条“某些环节没有值,程序就会发生异常,于是我们把感叹号(!)改为问号(?),代码如下所示:
emp.dept?.comp?.name

访问限定

访问范围
  • 模块。模块是指一个应用程序包或一个框架。
  • 源文件。源文件指的是Swift中的.swift文件。
访问级别

Swift提供了3种不同访问级别,对于访问修饰符:public、internal和private。 这些访问修饰符可以修饰类、结构体、枚举等面向对象的类型,还可以修饰:变量、常量、下标、元组、函数、属性等内容。

  • public。 可以访问自己模块中的模块的任何public实体,如果使用import语句引入其他模块,可以访问其它模块中的public实体。

  • internal。 缺省访问限定。只能访问自己模块的任何internal实体,不能访问其它模块的internal实体。

  • private。只能在当前源文件中使用的实体,称为私有实体。使用private修饰,可以用作隐藏某些功能的实现细节。

image.png

如上图:

1、在模块1中import模块2后,模块1可以访问模块2中的源程序文件1的public实体。
2、在模块1中import模块2后,模块1不可以访问模块2中的源程序文件2的internal实体。
3、在模块2中源程序文件1和源程序文件2可以相互访问。
4、在模块2中import模块1后,模块2不可以访问模块1中的源程序文件2中的private实体。
5、在模块1中,源程序文件1也不可以访问源程序文件2中的private实体。

使用访问级别最佳实践
1、统一性原则
  • 原则1。 如果一个类型(类、结构体、枚举)定义为internal或private,那么类型声明的变量或常量不能使用public访问级别。

  • 原则2。函数的访问级别不能高于它的参数和返回类型(类、结构体、枚举)的访问级别。

//访问限定
private class Employee2 {
    var no: Int = 0
    var name: String = "Tony"
    var job: String?
    var salary: Double = 0
    var dept: Department2?
}

internal struct Department2 {
    var no: Int = 0
    var name: String = ""
}

//违背统一性原则1
//public let emp2 = Employee2()  //编译错误
//internal let emp2 = Employee2()  //编译错误

private let emp2 = Employee2()

//违背统一性原则1
//public var dept2 = Department2() //编译错误
internal var dept2 = Department2()

//违背统一性原则2
//public func getEmpDept(emp: Employee2) ->Department2? {
//    return emp.dept
//}

private func getEmpDept(emp: Employee2) ->Department2? {
    return emp.dept
}
2、设计原则
  • 如果我们编写的是应用程序,应用程序包中的所有Swift文件和其中定义的实体都是供本应用使用的,而不是提供给其他模块使用,那么我们就不用设置访问级别了,即使用默认的访问级别。
  • 如果我们开发的是框架,框架编译的文件不能独立运行,因此它天生给别人使用的,这种情况下要详细设计其中的Swift文件和实体的访问级别,让别人使用的可以设定为public,不想让别人看到的可以设定为internal或private。
3、元组类型的访问级别

元组类型的访问级别遵循元组中字段最低级的访问级别,例如下面的代码:

private class Employee2 {
    var no: Int = 0
    var name: String = "Tony"
    var job: String?
    var salary: Double = 0
    var dept: Department2?
}
 struct Department2 {
    var no: Int = 0
    var name: String = ""
}
private let emp2 = Employee2()
var dept2 = Department2()
private var student1 = (dept2, emp2)//元组类型的访问级别遵循元组中字段最低级的访问级别
4、枚举类型的访问级别

枚举中成员的访问级别继承自该枚举,因此我们不能为枚举中的成员指定访问级别。例如下面的的代码:

 public enum WeekDays {
    case Monday
    case Tuesday
    case Wednesday
    case Thursday
    case Friday
}

相关文章

  • Swift--Swift语言中的面向对象特性

    Swift语言中的面向对象类型 枚举 结构体 类 可选链 访问限定 Swift语言中的面向对象类型 面向对象概念的...

  • OC面向对象

    OC面向对象—封装 一、面向对象和封装 面向对象的三大特性:封装(成员变量)、继承和多态 在OC语言中,使用@in...

  • 面向对象的继承

    继承--原型创建对象在面向对象的语言中,存在了三大特性—封装、继承、多态。我们前面一直说javascript是面向...

  • 【一起来烧脑】一步学会TypeScript入门

    字符串新特性变量和参数新特性函数新特性匿名函数for of循环TypeScript语言中的面向对象特性 理解ES5...

  • 2018-01-17 OC基础概念

    OC的理解与特性 OC 作为一门面向对象的语言, 自然具有面向对象的语言特性: 封装 继承 多态. 它既具有静态语...

  • 换个角度,用OO看世界

    何宏伟 [嵌牛导读] OO,Object-Oriented,面向对象。对于将C++/Java这类具有面向对象特性语...

  • 重学iOS——4.三大特性和一些小trick

    简介 OC作为一门优秀的面向对象的开发语言,那么必不可少的特性就是:封装、继承、多态。面向对象的三大特性也是OC语...

  • 面向对象编程(二)

    面向对象编程(二) -------面向对象的基本特性 1、面向对象的基本特性 面向对象的编程是把现实客观存在的...

  • 《Java从小白到大牛》之第10章 面向对象基础(上)

    《Java从小白到大牛》纸质版已经上架了!!! 面向对象是Java最重要的特性。Java是彻底的、纯粹的面向对象语...

  • 面向对象

    面向对象:OOP 面向对象三大特性

网友评论

      本文标题:Swift--Swift语言中的面向对象特性

      本文链接:https://www.haomeiwen.com/subject/pjhypctx.html