Swift入门基础:构造函数、下标、计算属性

这篇具有很好参考价值的文章主要介绍了Swift入门基础:构造函数、下标、计算属性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前文介绍了可选类型和闭包,这两个概念在做Object-C时没有遇到,转做Swift又必须面对的。当然除了上述两个概念外,还有构造函数、下标、计算属性等等。这次我们就分别介绍下。

 

构造函数

构造函数是一种特殊的函数,主要用途是在创建对象时,初始化对象和分配空间,并为对象成员变量进行初始值。在Swift语言中,所有的构造函数由init来实现。

构造函数分为以下几种:

  • 自定义构造函数

  • 便利构造函数

  • 可失败构造函数

下面从这几方面分别介绍

自定义构造函数

除了系统提供的init默认构造函数外,Swift还支持自定义构造函数。自定义构造函数分为必选(no-Optional)和可选(Optional)属性构造函数。下面分别说明。

必选(no-Optional)属性构造函数

必选属性构造函数,顾名思义,就是成员属性的类型是基本类型的构造函数。

必选属性构造函数有些什么注意点呢?

举例来说明。

//自定义Student类
class Student {
  //姓名
  var name:String
  //年纪
  var age:Int
}
//实例化
var st = Student()

上述代码,编写完成后,就会报两个错误。如下图所示:

swift构造函数,IOS开发,swift,开发语言,ios

 原因:类中定义了必选属性,但是没有赋初值。所以,对于必选构造函数来说,必须通过构造函数为这些必选属性分配空间并且设置初始值。

那上面的错误怎么解决呢?通过对Student进行初始化,就解决了错误。如下代码所示。

class Student {
    var name:String
    var age:Int
    
    init() {
        name = ""
        age = 0
    }
}
var st = Student()

子类构造函数

上述一个简单的类,没有子类继承,问题就简单一点。若是有子类继承的情况,子类构造函数又会怎么样的呢?

我们就针对Student类,派生一个子类Schoolchild(小学生)。Schoolchild继承Student类,并且按Student类方式,初始化好成员属性(grade),如下代码:

class Student {
    //姓名
    var name:String
    //年龄
    var age:Int
    
    init() {
        name = ""
        age = 0
    }
}
var st = Student()

class Schoolchild:Student {
    //年级
    var grade:Int
    
    init() {
        grade = 0
    }
}

上述代码在实际项目中是编译失败的,错误如下图所示:

swift构造函数,IOS开发,swift,开发语言,ios 原因是,Schoolchild继承Student类,init方法在父类已经实现了,子类又重复实现init方法。要解决这个报错,要么重载init函数,要么重写init函数。如下所示。

//重写方式,重写(override)就是方法名,参数和返回值跟父类的一样。
override init() {
   grade = 0
}

//重载方式,重载(overload)就是方法名一样,参数或返回值不一样。
init(aGrade:Int) {
    grade = aGrade
}

通过重载或者重写,解决了上面的问题。下面在看看构造函数的调用时机。

子类调用父类构造函数的时机

在子类构造函数,会调用super.init()来完成父类的初始化。那问题来了,super.init是在什么时机调用呢?子类属性初始化前调用还是之后调用呢?

如下代码所示:

override init() {
        super.init()    //在前调用
        grade = 0
}

override init() {
        grade = 0
       super.init()  //在后调用
}

实际情况是,在初始化之后调用是正确的。在前调用会报错。错误如下:

swift构造函数,IOS开发,swift,开发语言,ios

 原因就是:Swift的规则是先初始化好子类属性,再初始化父类的属性。可以理解:先初始化好子类数据,再初始化上一级(父亲)数据,这样一层层往上递归。

再问个问题,子类和父类的析构过程又是怎么样的呢?通过实例证明,先析构子类,再析构父类。

swift构造函数,IOS开发,swift,开发语言,ios

小小结:

1.自定义子类时,需要在构造函数中,首先为本类定义的属性设置初始值。

2.然后再调用父类的构造函数,初始化父类中定义的属性。

3.析构时,先析构子类,再析构父类。

可选(Optional)属性的构造函数

上述是针对必选类型的构造函数,那么可选属性的构造函数有是什么情况?

自定义Student2类,不过name和age为可选类型

class Student2 {
     //姓名
    var name:String?
    //年纪
    var age:Int?
}
//实例化
var st = Student2()

上述Student2在实际项目中是能编译通过的,虽然没有实现init构造函数。那为什么不写init构造函数就能编译通过呢?原因:

1.可选属性不需要设置初始值,默认都是nil。

2.可选属性在设置数值的时候才分配空间的,是延迟分配空间。

自定义构造函数小结

1.非Optional属性,都必须在构造函数中设置初始值,从而保证对象在被实例化的时候,属性都被正确初始化。

2.在调用父类构造函数前,须保证本类的属性都已经完成初始化。

3.Swift中的构造函数不用写func。

4.可选属性的类不必实现构造函数方法。

默认属性值

在构造函数中,还有一写法:默认属性值,前面讲到的是在构造函数(init函数)中为存储型属性设置初始值;其实,还可以在属性声明时为其设置默认值。这样做的好处:能让构造函数更简洁、更清晰,并通过默认值来自动推导出属性的类型。

class Student3 {
    // 设置默认值
   //姓名
    var name = "name"
    //年龄
    var age = 10
    
    //好处:不用再实现init构造函数,同时不用声明类型,
    //编译器自动推断出类型。
}
var st3 = Student3()

convenience便利构造函数

1.大部分情况下,我们都是使用自定义构造函数,但在某特定情况下,也会编写便利构造函数。

2.由convenience 关键字修饰的构造函数就是便利构造函数。

3.便利构造函数针对某些场景特别使用,具有一定的方便性。究其实质是简化自定义构造函数。

便利构造函数的特点

1.可以返回 nil.

2.便利构造函数可调用self.init()函数.

3.便利构造函数不能被重写或者super调用.

便利构造函数的优势

可以定义便利构造器来调用同一个类中的自定义构造器,并为其参数提供默认值。可以使用便利构造器来创建一个特殊用途的实例。

便利构造器实例

//实例1:特定用途的构造函数(限制了age的范围)
convenience init?(name: String, age: Int) {
    if age < 20 || age > 100 {
        return nil
    }
    self.init(name:name age:age)
}
//实例2:类的继承 (缩减的输入参数)
class mainClass {
    var num1 : Int // 属性
    init(num1 : Int) {
        self. num1 = num1
    }
}

class subClass : mainClass {
    var num2 : Int
    init(num1 : Int, num2 : Int) {
        num2 = num2
        super.init(num1: num1)
    }

    // 便利构造函数只需要一个参数
    override convenience init(num1: Int)  {
        self.init(num1: num1, num2:0)
    }
}
let res = mainClass(num1: 20)
let res2 = subClass(num1: 30, num2: 50)
//使用便利构造函数,简化了参数。

便利构造函数应用场景

1.用给定参数来判断是否要创建对象,不需要像自定义构造函数那样,必须实例化一个对象。

2.在实际应用中,对已有类的构造函数进行扩展,可以使用便利构造函数,从而达到简化对象的创建的目的。

可失败构造器

如果一个类、结构体或枚举类型的对象,在构造自身的过程中有可能失败,则为其定义一个可失败构造器。

变量初始化失败可能的原因,一般有如下几种:

1.传入了无效的参数值而失败。

2.缺少某些的外部资源而失败。

3.没有满足特定条件的失败。

为了更好地处理这种构造函数可能会失败的情况。我们一般添加一个或多个可失败构造器。其语法为在init关键字后面加添问号(init?) 或者(init!)。

实例:

class Student3  {
    let name: String
    init?(name: String) {
        if name.isEmpty { return nil }
        self. name = name
    }

    init!(name: String) {
        if name.isEmpty { return nil }
        self. name = name
    }
}
let st4 = Student3(name: "Li lei")
let st5 = Student3(name: "")
//即当初始化Student3的时候,输入一个为空的name,就有可能初始化失败。

可失败构造器注意点:

1.通过在 init 关键字后面添加问号init?或者Init!(后者代表强制解包)。

2.可失败的构造函数里面应该有一个 return nil 的语句(没有也不报错)。

3.通过可失败的构造函数构造出来的实例是一个可选型,所以配合解包。

以上就是构造函数的相关知识。

下标

前面讲到了构造函数,这里再讲下标。

什么是下标

在Swift语言中,为了存储或获取数据的方便,针对类、结构体和枚举类型,创造了下标的概念。

通过使用下标的索引,可以快速地设置或者获取数据,而不需要再调用对应的存取方法了。举例来说,用下标访问Array实例中的元素时,可以写作array[index],访问Dictionary实例中的元素时,可以写作dictionary[key]。

下标语法

下标是使用subscript关键字来定义,类似函数,带有参数和返回值。其中参数和返回值分别作为入参和获取值。

subscript的内部实现:一个get块和一个可选的set块。get块用于返回值,set块用于设置值。

示例如下:

subscript(index: Int) -> Int {
    get {
      // 返回一个适当的Int类型的值
    }
    set(newValue) {
      // 执行适当的赋值操作
    }
}

其中newValue是一个隐藏的参数,其类型和返回类型相同。如同计算型属性,可以不指定setter的参数(newValue)。如果不指定参数,setter 会提供一个名为 newValue 的默认参数。

对于只读下标的声明,可以通过省略 get 关键字和对应的大括号组来进行简写:

subscript(index: Int) -> Int {

   //返回一个适当的 Int 类型的值

}

小小结:

1.使用subscript关键字定义下标。

2.下标可以接受多个参数且类型任意。

3.下标支持返回类型,且类型任意。

4.下标可以没有set方法,但必须要有get方法。如果只有get方法,可以省略get。

5.下标有个默认参数(newValue),在不指定参数时提供。

6.下标的参数不能设置默认值,也不能设置为in-out类型。

下标实例

//实例1:获取下标值
class AddTable {
    let adder: Int
    subscript(index: Int) -> Int {
        return adder + index
    }
}
let addTable = AddTable(adder: 10)
print("after adder:\(addTable[3])")
// 打印“after adder:13”

在上例中,创建了一个AddTable实例,在输入下标索引之后,将在索引基础上再加上10,并把结果返回。这里演示获取下标数据的方式。

实例2:快速设置值

下标通常作为访问集合,列表或序列中元素的快捷方式。可以针对特定的类或结构体功能,用最恰当的方式实现下标。

例如,Swift的Dictionary类型实现下标用于对实例中储存的值进行存取操作。为字典设值时,在下标中使用和字典的键类型相同的键,并把一个和字典的值类型相同的值赋给这个下标:

var legs = ["Cat": 2, "Dog": 3, "Bird": 4]

legs["Ant"] = 2

上例定义一个名为 legs 的变量,并用一个包含三对键值的字典字面量初始化它。legs 字典的类型被推断为 [String: Int]。字典创建完成后,该例子通过下标将 String 类型的键 Ant 和 Int 类型的值2添加到字典中。

类型下标

前面讲的都是实例的下标,实例下标是在特定类型的一个实例上调用的下标。我们还可以定义一种在类型自身上的下标。这种下标被称作类型下标。一般通过在subscript关键字之前写下static关键字的方式来表示一个类型下标。下面的例子展示了如何定义和调用一个类型下标:

enum Color: Int {
    case mercury = red, green, blue, black, yellow
    static subscript(n: Int) -> Color {
        return Color(value: n)!
    }
}
let black = Color[3]  //注:下标是从0开始
print(black) //black

注意:类类型可以使用class关键字来代替 static,它允许子类重写父类中对下标的实现。

至此,Swift入门基础,下标也介绍完了,下面介绍属性的概念。

计算属性

前面讲到了构造函数和下标。在Swift开发过程中,构造函数和下标的使用非常实用,当然还有一个也很实用的就是属性。

属性与成员变量的区别

首先先说下属性与成员变量的区别。属性具有set、get方法,是允许其他对象访问属性的。而成员变量恰恰相反,成员变量主要用于类内部,不与外界接触,其具有一定的私有性。

属性与成员变量的内部机制分别是:属性是公开的(public),其在创建过程中自动生成set和get方法。外界可以通过set或get方法访问;而成员变量是私有的(private),且不会生成set、get方法,外界无法访问。

在Swift中,属性分为存储属性、计算属性、懒加载属性、类属性。下面分别介绍

存储型属性

存储型属性(sorted variable):它具有属性的特性(有get或set方法),但是它还有个新特性:能存储一个常量或变量。我们可以理解为可以进行赋值和取值的变量。

class car {
   //成员变量
   var name:String="b"
   
   //存储属性
   var name:String{
      get{
          return self.name
      }
      set{
          self.name= newValue
      }
}

计算属性

计算型属性(computed variable):仅有get(readOnly语义)或有get+set的属性。当有get+set的属性,也只是作为其他属性的外部接口,供外部调用。

我们可以从字面上理解计算型的属性,这种属性没法存储值。设计出计算型属性只是为了调用其他属性而包装的读取方法,本身没有内存空间,也就不能赋值。

举例说明

//实例1
var title: String {
   get {
      return "所选学课:" + "\(name)"
   }
}

//实例2:get+set正确的使用方法:作为其他属性的外部接口:
private var _squre: Double = 0.0
var squre: Double {
        get {
            return _squre
        }

        set {
            if (newValue <= 0) {
                print("newValue = \(newValue)")
            } else {
                _squre = newValue
            }
        }
 }

小小结:

1.存储型属性,能存储数据。方便存储

2.计算型属性,不分配独立的存储空间,不能存储数据,只提供get和set方法。

懒加载属性

懒加载属性,是在属性前加上lazy关键字,起到延迟加载的作用。

还有其他的特性:

1.必须有默认值

2.在第一次访问的时候才被赋值

3.有线程安全隐患。

类型属性

1.使用static修饰,并且是全局变量

2.必须有值

3.类型只会被初始化一次

//举例:
static var default: Person = Person()

以上就是属性的介绍。

到这里,关于构造函数,下标,属性的概念都介绍了。文章来源地址https://www.toymoban.com/news/detail-797002.html

到了这里,关于Swift入门基础:构造函数、下标、计算属性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • iOS_Swift高阶函数

    1.1 定义 高阶函数:higher-order function 如果一个函数: 接受一个或多个函数当作参数 把一个函数当作返回值 那么这个函数就被称做高阶函数。 例如: 看着不像是函数作为参数,是因为 Swift 尾随闭包 Trailing Closure 的特性。 Swift 允许当函数的最后一个参数是闭包时,可以以紧跟

    2024年02月04日
    浏览(26)
  • Swift 单元测试入门

    含义:编程语言中的单元测试是为了确保编写的代码按预期工作。 给定一个特定的输入,希望代码带有一个特定的输出。通过测试代码,能够给当前的重构和发布建立信心,因为将能够确保代码在成功运行的测试套件后按预期工作。 单元测试是运行和验证一段代码(称为“

    2024年02月11日
    浏览(24)
  • iOS_Swift函数派发机制

    前言: 函数调用机制 是程序判断使用哪种途径去调用一个函数的机制,即 CPU 在内存中找到该函数地址并调用的过程。 了解 函数的调用机制 ,对于写出高性能代码来说十分有必要。 派发效率从高到底: Static dispatch Table dispatch Message dispatch Static dispatch 静态派发,即直接地址

    2024年02月05日
    浏览(20)
  • iOS开发Swift-8-类的继承,方法重写,构造器,枚举类型,可选类型,强制解包,可选绑定,隐式可选类型...

    1.类的继承  2.方法的重写 3.构造器: 创建对象;给对象进行初始化  4.枚举类型 5.枚举的原始值 6.枚举的简写  7.可选类型  8.强制解包 9.可选绑定  10.隐式可选类型  11.可选类型自动赋值

    2024年02月09日
    浏览(31)
  • swift基础语法

    参考教程 https://www.runoob.com/swift/swift-data-types.html swift代码规范 https://juejin.cn/post/7129465308376465422 必须要有苹果电脑且安装Xcode Swift是类型安全的语言,编译时会进行类型检查 可以使用 import 语句引入任何的Objective-C(C语言的严格超集) 创建macOS playground则引入Cocoa,Cocoa由Objec

    2024年01月21日
    浏览(36)
  • Swift基础

    本文是个比较简单的学习笔记,更详细的内容见 Swift官方文档 Swift标准库用 和 == 运算符定义了 、=、=,所以实现 Comparable 的 运算符就会自动得到这些运算符的实现,实际上 Comparable 继承自 Equatable,所以 == 运算也是必须实现的,以下是示例代码 虽然是讲继承,但代码中的注

    2024年02月07日
    浏览(35)
  • Swift语言基础

    Swift 是一种支持多编程范式和编译式的开源编程语言,苹果于2014年WWDC(苹果开发者大会)发布,用于开发 iOS,OS X 和 watchOS 应用程序。 Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制。 Swift 在 Mac OS 和 iOS 平台可以和 Object-C 使用相同的运行环境。 官方手册: swift官

    2024年02月12日
    浏览(30)
  • Swift学习笔记(一)基础语法

    浅学一下Swift,这篇笔记做个记录 依然是Xcode,关于Xcode就不多介绍了。 let和var分别用来表示常量和变量,无论是let还是var,作用都是为某个具体量值取了一个名字,这种方式叫做量值的声明。在量值的有效作用域内,开发者可以使用这些名称来获取具体的量值

    2024年01月17日
    浏览(35)
  • iOS开发Swift-基础部分

    系统可通过赋初始值进行自动推断。 平时可加可不加,同一行中有两句话必须加。 Int           UInt(最好不用) Double 64位 很大/高精度情况下使用 15位小数 Float 32位 对精度要求不高的情况下用 6位小数 十进制数   17 二进制 0b前缀 0b10001 八进制 0o前缀 0o21 十六进制 0x前缀

    2024年02月11日
    浏览(39)
  • iOS(一):Swift纯代码模式iOS开发入门教程

    1.修改 AppDelegate.swift 和 ViewController.swift 文件 2.删除 SceneDelegate.swift 和 Main.storyboard 文件 3.修改如图所示项 安装 CocoaPods 初始化项目(添加 Podfile 配置文件) 修改 Podfile 文件 安装 打开 ExDemoApp.xcworkspace 项目并向 ViewController.swift 添加示例代码 运行效果 安装 QMUIKit 方式一:触发

    2024年02月09日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包