1. 类的创建

类是属于用户自定义的数据类型,并且该类型具有一定的行为能力,也就是类中所描述的方法。 通常来说,一个类的定义包含两部分内容,一部分是该类的属性,另一部分是它所拥有的方法。以汽车这个类来说,每种车都有自己的品牌,车龄,出厂日期,耗油量的等属性,此外汽车还拥有启动,刹车,转弯,倒车等属于汽车所具有的行为。 和定义枚举和结构体类似,在定义类的时候,使用class作为关键字,并把类的具体内容放置在一对大括号中。

1
2
3
4
5
 class 类名
 {
    //属性方法
    //方法列表 
 }

以汽车形象为样本,创建一个汽车类。

1
2
3
4
5
 class Car 
 {
    var brand: String = "" 
    var speed: Int = 0
 }

在上记代码中,使用class关键字定义了一个名为Car的类,它拥有brand和speed两个属性。Swift要求在定义类时,类的属性要进行初始化,所以这里设置brand属性的默认值为空的字符串,而speed属性的默认值为0。

其中可以在定义类的时候,给它指定自定义的init初始化方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 class Car 
 {
    var brand: String 
    var speed: Int

    init()
    {
        self.brand = ""
        self.speed = 0
    }
 } 

2. 类属性的set和get方法

了解java的同学都应该知道,在类中可以对属性进行set和get设置。在Swift中同样可以对类属性进行set和get设定操作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 class Hero
 {
    var damage : Int = 10 // 伤害
    var level : Int        // 级别
    {
       get 
       {
           return self.damage/10
       }
       set(newLevel)
       {
           self.damage = newLevel * 10
       }
    }
 }

3. 类属性的willSet和didSet方法

通过给属性添加willSet和didSet方法,可以给类添加属性观察者。属性观察者可以观察属性值得改变,并对此做出相应的反应。当设置属性的之时,属性观察者就被调用,即使新值和原值相同时也会被调用。 可以单独或同时使用下面的两个方法,以进行属性观察者的定义:willSet方法在设置属性值之前调用,而didSet方法则在设置属性值之后被调用。 当实现willSet观察者时,新的属性值作为常量参数被传递。可以为这个参数起一个名字,如果不命名,则这个参数就被默认命名为 newValue。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 class Hero {
    var damage: Int = 10
    var level: Int = 1 {
        willSet {
            print("level的新值=\(newValue)")
        }
        didSet {
            if(oldValue < level) {
                print("英雄升级!")
            } else {
                print("挑战失败,未能升级!")
            }
        }
    }
 }

 let hero = Hero()
 hero.level = 2
 hero.level = 2

在上面的代码中,level属性进行了两次赋值set操作,所以willSet和didSet方法都被调用了两次,在控制台的最终结果如下所示:

1
2
3
4
 level的新值=2
 英雄升级!
 level的新值=2
 挑战失败,未能升级!

4. 类的静态方法

在移动开发项目中,你会经常发现在一些工具类中,定义了大量的静态方法。如果某些操作不依赖具体实例,那它就是静态的,你可以将方法定义为静态方法。反之如果某些操作是依赖具体实例的,那它就应该实例化的。 在Swift环境中,可以为类,结构体和枚举等类型等类型定义静态方法,也称为类型方法。在为结构体和枚举定义静态方法时,可以使用 static 关键字;在为类定义静态方法时,可以使用 class 关键字。

注意:使用class关键字声明的静态方法,在子类中可以被覆写

5. 类的析构

Swift和Objective-C一样是通过自动引用计数(ARC)技术,来实现对实例的内存管理的。Swift会自动释放不再需要的实例以释放资源。所以当你的实例被释放时,不需要手动去清理。 但是,当释放程序中的资源时,你可能需要额外进行一些清理。例如:如果你创建了一个自定义的类来打开文件,并写入若干数据,就需要在类实例被释放之前关闭该文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 class FileManager
 {
     func loadFile()
     {
         print("加载文件")
     }

     func writeFile()
     {
         print("写文件")
     }

     deinit()
     {
         print("关闭文件")
     }
 }

如果创建了名为fileManager的实例,最后将fileManager的实例设置为 nil。系统就会自动调用析构函数。

6. 类的继承

在Swift中,类可以调用和访问父类的方法,属性和下标脚本,也可以重写他们。 在使用继承功能之前,创建一个基类,即没有继承其他类的类:

1
2
3
4
5
6
7
 class Animal
 {
     func say()
     {
        print("I'm an animal.")
     }
 }

这里定义了一个名为Animal的基类,它拥有一个名为say的方法。接着定义一个继承自Animal的子类:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 class Dog : String
 {
    var name: String

    init(name: String)
    {
        self.name = name
    }

    override func say()
    {
       print("I'm dog, my name is \(name)")
    }
 }

如果不希望父类的属性,下标或方法被重写,它们之前添加final修饰符。

7. 类的延迟加载属性

延迟加载属性是指当第一次被调用的时候,才会对其进行初始化操作的属性。 当一个类拥有一个重度且不经常使用的属性时,比如该属性是一个复杂的类,或者属性在初始化时需要从本地或网络加载所需的资源。此时在属性声明前使用lazy关键词,可将该属性标示为一个延迟加载属性,这样只有在使用到该属性时,才会对该属性进行初始化操作,从而提高程序的运行效率。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 class A
 {
    var photo: UIImage = UIImage(named: "pic1")!
 }

 class B
 {
   lazy var a: A = A()
 }

 let b = B()
 print(b.a.photo)