Swift学习笔记02
函数
独立的能够重复使用的功能模块.对于调用者来说,函数就像是一个独立的黑盒子,调用者在使用函数提供的功能时并不需要了解它的内部实现。Swift支持全局函数和方法,方法是跟类或者某种类型的对象相关联的函数
定义一个函数:
func sayHello(personName: String, alreadyGreeted: Bool) -> String {
if alreadyGreeted {
return "怎么又是你," + personName + "!"
}
let greeting = "hello, " + personName + "!"
//如果函数的返回类型不是void 那么函数中一定有return语句
return greeting
}
调用函数:
调用函数,函数名(参数值)
如果有两个以上的参数,第二个开始需要写上参数名
如果想省略外部参数名 在构建函数的时候 可以加上 _ 表示省略外部参数名
print(sayHello("王大锤", alreadyGreeted: true))
print(sayHello("JACK", alreadyGreeted: false))
Swift中,函数的参数可以是inout参数,所谓inout参数是指可以在函数中被修改并影响到调用者的参数
func swap(inout x: Int, inout _ y: Int) -> Void {
//(x, y) = (y, x)
let temp = x
x = y
y = temp
}```
这个交换值的函数,使用Inout参数之后,函数外的X,Y也相应的改变了值
##字典
字典(存放键值对组合的容器) 字典中的每个元素都是由两部分构成的, 冒号前面是键冒号后面是值
创建一个字典:
```swift
var dict: [String: String] = ["abacus": "算盘", "abnormal": "异常的", "hello" : "你好", "good": "好的"]
遍历字典
//遍历字典中所有的值
for value in dict.values {
print(value)
}
//遍历字典中所有的键
for key in dict.keys {
print("\(key) ----> \(dict[key])")
}
//直接通过一个元组获得字典中的键和值
for (key, value) in dict {
print("\(key) ----> \(value)")
}
闭包
在swift中函数是一种类型,这也就意味着函数可以作为变量或者常量的类型,同理函数也可以作为另一个函数的参数或者返回值
func foo(array: [Int], fn: (Int, Int) -> Int) -> Int {
var sum = 0
for x in array {
sum = fn(sum, x)
}
return sum
}
print(foo(a, fn: { (a, b) -> Int in
return a % b
}))
//省略掉类型和不必要的括号
print(foo(a, fn: {a, b in a + b}))
// 省略参数名
print(foo(a, fn: {$0 + $1}))
// 尾随闭包
print(foo(a) {(a, b) -> Int in
return a + b
})
print(foo(a) {$0 + $1})
如果函数的最后一个参数是闭包可以写成尾随闭包的形式;将闭包放到函数参数的圆括号外面写在一对花括号中;如果函数后面有尾随闭包且函数的圆括号中没有参数,那么函数的圆括号可以省略;闭包的返回类型可以省略掉,如果只执行一句代码,return也可以省略掉。
面向对象的思想(类)
对象是接受消息的单元
对象都有属性和行为(静态和动态)
对象都属于一个类
每个对象都是独一无二的
类:对象的蓝图和模板类是抽象的,对象是具体的
消息:对象之间通信的方式,通过对象互发消息可以构造出复杂的系统
首先我们定义一个学生的类
class Student {
//数据抽象 - 找到和学生相关的属性
var name: String
var age: Int
//初始化方法 (构造方法/构造器) - constructor
init(name: String, age: Int) {
self.name = name
self.age = age
}
//行为抽象 - 找到和学生相关的方法
func eat(foodName: String) -> Void {
print("\(name)正在吃\(foodName)")
}
func study(courseName: String) {
print("\(name)正在学习\(courseName)")
}
}
创建对象,调用初始化方法.然后给对象发消息
let stu1 = Student(name: "北林木笔", age: 18)
stu1.eat("酸辣粉")
stu1.study("高等数学")
名为Student的类中,有name和age两个属性,分别代表人的姓名和年龄;然后定义了两个方法,分别代表了人吃饭和学习的行为。除此之外,在Student类中还有一个init方法,它是类的初始化方法,当类创建一个对象时,需要使用init方法进行对象属性的初始化.如果对象没有属性,也可以不用init方法
类的继承
继承:从已有的类创建新类的过程
提供继承信息的称为父类(超类/基类)
得到继承信息的 称为子类(派生类/衍生类)
通常子类除了得到父类的继承信息还会增加一些自己特有的东西
所以子类的能力一定比父类更强大
继承的意义在于子类可以复用父类的代码并且增强系统现有的功能
我们先创建一个父类,人这个类
//性别的枚举
enum Gender {
case Male
case Female
}
class Person {
var name: String
var age: Int
var gender: Gender
init(name:String, age:Int, gender:Gender){
self.name = name
self.age = age
self.gender = gender
}
func eat() {
print("\(name)正在吃饭.")
}
}
人这个类属性有年龄,名字,性别.行为有吃东西然后我们再创造一个学生类
class Student: Person {
var major: String
init(name:String, age:Int, major:String, gender:Gender){
self.major = major
super.init(name: name, age: age, gender: gender)
}
func study(courseName: String) {
print("\(name)是\(major)专业的学生")
print("\(gender == Gender.Male ? "他" : "她") 正在学习\(courseName)")
}
}
学生类继承于人类,所有他的对象也拥有人类对象的属性.而且学生类相对于人类来说又有新的属性(主修课程)和方法(学习).这就是子类对父类的扩展。显然子类拥有比父类更多的能力,也就是说,继承一定是让子类扩展父类的能力而绝不会缩小父类的能力
多态
多态简单的说是同样的方法执行了不同的行为,就好比猫和狗都有发出叫声的行为,但是发出的声音是完全不一样的。
例如我们先建一个宠物的类
enum Gender {
case Male
case Female
}
class Pet {
var nickname: String
var gender: Gender
var age: Int
init(nickname:String, gender: Gender, age: Int){
self.nickname = nickname
self.gender = gender
self.age = age
}
func shout(){
print("\(nickname)正在叫")
}
}```
再建两个宠物类的子类
```swift
class Cat: Pet {
var hairColor: String
init(nickname: String, gender: Gender, age: Int, hairColor:String) {
self.hairColor = hairColor
super.init(nickname: nickname, gender: gender, age: age)
}
override func shout(){
print("\(nickname):喵喵喵喵.....")
}
}
class Dog: Pet {
var isLarge: Bool
init(nickname: String, gender: Gender, age: Int, isLarge:Bool) {
self.isLarge = isLarge
super.init(nickname: nickname, gender: gender, age: age)
}
override func shout() {
print("\(nickname): 汪汪汪....")
}
}
父类中宠物已经有了shout的这个方法,但是由于猫和狗实现的方法不一样.所以我们要重写父类的方法,需要在方法前添加override关键字
重写有时也被称为置换、覆盖、覆写
然后我们创建猫和狗的对象来调用这个方法
let petsArray = [
Cat(nickname: "加菲", gender: .Female, age: 2, hairColor: "黄色"),
Dog(nickname: "大黄", gender: .Male, age: 1, isLarge: true),
]
for pet in petsArray {
pet.shout()//加菲:喵喵喵喵..... 大黄: 汪汪汪....
}
同样的对象类型(pet)接受相同的消息(调用相同的方法)但是做了不同的事情。