Swift语言入门
枚举、类和结构体的声明和使用
// 枚举
// 枚举能为一组相关值定义一个共同的类型,通过enum关键字来声明枚举类型
enum Direction {
case east
case west
case south
case north
} // 在声明时也可以把多个值声明在一个case语句中
enum AppleOS {
case iOS, macOS, watchOS, tvOS
}
var walk: Direction = Direction.north // 可以通过点语法来访问枚举类型中的特定值
// 这里可以将类型标注(: Direction)去掉,swift完全可以根据我们的赋值来判断变量的数据类型
walk = .east
// 修改枚举变量 :因为swift已经推断出它是哪一个枚举类型了,所以可以直接使用点语法来进行赋值
// 使用switch语句来匹配枚举值
switch walk {
case .east:
print(“正在往东走”)
case .west:
print(“正在往西走”)
case .north:
print(“正在往北走”)
case .south:
print(“正在往南走”)
} // 如果swift语句没有将d所有情况都考虑完的话,还是需要default分句来z保证switch语句的完备性的
var direction = Direction.east
switch direction {
case .east:
print(“正在往东走”)
default:
print(“没有往东走”)
}
/* 类和结构体
是我们在编程中经常用到的一种灵活的构造体,我们可以为类和结构体定义属性和添加方法,从而拓展其功能
和枚举类型一样,当我们声明一个类或者结构体的时候,相当于声明了一个新的swift类型*/
// 类和结构体的声明(只是描述了对象的固有属性,并没有表示某个具体的对象)
// 结构体:e.g 描述分辨率对象(分辨率有宽和高两个属性)
struct Resolution {
var width = 0
var height = 0 // 声明在类和结构体中的变量或者常量,通常称之为属性
}
// 类:e.g 游戏中的角色 (假设有名称(name)、血量HP(health point)和攻击力ATK(attack)三个属性)
class Player {
var name = “”
var HP = 100 // 血量
var ATK = 30 // 攻击力
}
// 类和结构体的实例 (为了能够让类和结构体表示具体的对象,需要将其实例化)
/* 类和结构体都是用构造语法来生成新的实例。
构造语法最简单的形式:在结构体或者类的类型名称后面跟随一对括号
通过这种方式创建的类或者结构体的实例,他们的属性都会被初始化成我们声明的时候设置的默认值*/
var resolution = Resolution()
var player1 = Player()
var player2 = Player()
/* 命名:之前给常量、变量、函数命名的时候使用的是驼峰命名法,枚举、结构体和类的命名方式其实也是驼峰命名法,
只有一点不一样的是,要求首个单词的首字母也要大写。这样当我们看到这样的名称时,就知道这是一个数据类型的名称,
而不是某个常量、变量或是函数的名称*/
// 属性的访问和修改 (通过点语法来实现)
resolution.width = 1920
resolution.height = 1080
player1.name = “玩家1”
player2.name = “玩家2”
player1.HP = player1.HP - player2.ATK // 使用符合运算符将这句代码写的简练一点 player1.HP -= player2.ATK
print("(player1.name) 受到 (player2.name) 的攻击,剩余血量 (player1.HP)")
// 类和结构体的差异
// 结构体:在声明之后,系统会自动生成一个成员逐一构造函数,用于初始化新的结构体实例中每一个成员的属性
// 类没有默认的这个逐一成员构造函数,但是类和结构体都可以自定义构造函数
/* 结构体是值类型的数据(这是结构体区别于类最重要的一点)
值类型被赋予一个变量、常量或者被传递给一个函数的时候,它的值会被复制
结构体是值类型的数据,意味着它的实例以及实例中所包含的属性,在代码传递的时候会被复制*/
var hd = Resolution(width: 1920, height: 1080)
var cinema = hd // 将 hd 的值复制后再赋值给 cinema
cinema.width = 2048
print(“cinema现在的分辨率宽是(cinema.width)”)
print(“hd的分辨率宽仍然是(hd.width)”) // 结果说明 cinema 的值在修改时不会影响 hd 的值
// 我们之前所学过的所有数据类型,比如Int, String, Double型都是通过值类型传递的,因为其实他们都是通过结构体来实现的;和结构体不同,类是引用类型
// 类是引用类型
// 引用类型在被赋予到一个常量、变量或者被传递到一个函数时,它的值是不会被复制的,而是引用已经存在的实例
var player = Player()
player.name = “玩家”
player.HP = 200
player.ATK = 50
var shadow = player
shadow.HP -= 30
print(“shadow现在的血量为(shadow.HP)”)
print(“player现在的血量也为(player.HP)”)
//当我们声明一个类实例的时候,系统会为我们创建一个实例;但是当我们将一个已经存在的类实例赋给一个常量或者变量的时候,系统不会像结构体那样复制一个值,而是让两个变量共同引用一个实例对象
// 类和结构体还有一个区别是:类是可以继承的
//类的继承
/一个类可以继承另一个类的方法、属性和其他特性。当一个类继承其他类时,继承类叫做子类,被继承的类叫做父类或者超类
在swift中,继承是区别类与其他类型的一个基本特征/
// 基类(不继承于其他类的类)
class Vehicle {
var currentSpeed = 0.0
func makeNoise() {
// 什么也不做 交通工具不一定会有噪音
}
}
// 子类的声明
// 声明语法:在类名的后面加上一个冒号,然后写上要继承的父类的名称
class Bicycle: Vehicle {
var hasBasket = false
}
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15
//子类除了能够访问本身的属性外,还可以访问到x从父类继承过来的属性和方法(声明在结构体或者类中的函数我们通常称之为方法,这些属性和方法都是可以访问和修改的
// 子类还可以被其他类继承
class Tandem: Bicycle { // tandem:双人自行车
var currentNumberOfPassengers = 0
}
let tandom = Tandem()
tandom.hasBasket = true
tandom.currentNumberOfPassengers = 2
tandom.currentSpeed = 22
// tandom继承了bicycle所有的属性,包括bicycle从其父类继承过的属性,这些属性我们都可以访问和修改
// 类的重写
class Train: Vehicle {
override func makeNoise() {
print (“哐哧哐哧哐哧~~”)
}
}
class Plane: Vehicle {
override func makeNoise() {
print(“呜–呜--”)
}
}
let train = Train()
let plane = Plane()
train.makeNoise()
plane.makeNoise()
bicycle.makeNoise()
// 构造函数(构造器)(会在实际化时被调用)
// 类和结构体在创建实例时,必须为所有属性设置合适的初始值,可以通过构造函数来实现实例的初始化
class Box {
var length: Double
var width: Double
var height: Double
init(length: Double, width: Double, height: Double) { //构造函数通过init关键字来实现
self.length = length
self.width = width
self.height = height //给要被赋值的属性加上一个self前缀,用来分辨哪一个是自己的属性,哪一个是用户输入的参数
}
init(cube sideLength: Double) {
length = sideLength
width = sideLength
height = sideLength
}
}
let Box = Box(length: 3, width: 2, height: 4)
let cube = Box(cube: 6)