Swift第三周学习总结
上周知识点回顾
标志符的命名规则
1.字母(Unicode字符)数字下划线,数字不能开头
2.大小写敏感
3.不能使用关键字做标志符
4.驼峰命名法,第一个单词全小写,以后每个单词首字母都大写
5.见名知意
运算符
- 算术运算符: + - * / %
- 关系运算符: == != > >= < <=
- 短路运算符:&& ||
- ? : 运算符
Exp1 ? Exp2 : Exp3;
元组(Tuple)
var stu:(ID:Int,name:String,gender:Bool,year:Int,high:Int) = (1001,"王大锤",true,23,168)
分支结构
if...else
if {}
else {
if {}
else{}
}
switch ....case
switch xxx{
case 1:
case 2:
defalut :
}
穷举法
穷尽所有的可能性直到找到正确的答案
数组
创建数组
var ah=[Int]()
var array3 = [99,22,11,22,145]
var array4 = [Int](count: 100, repeatedValue: 1)
var array5 = [String]()
var array6:[String] = []
var array7 = ["sha","haha","nn","qq","qqqq"]
var array8 = [String](count: 100, repeatedValue: "1")
//获取数组元素的个数
print(array8.count)
print(array7.count)
print(array5.count)
print(array6.count)
//对数组中的元素进行遍历,就是把他们取出来
for index in 0..
数组的三大特性(过滤,映射,规约)
let array = [1,5,8,55,51,45,53,4,554,57,42]
//1.过滤
let newarray=array.filter { $0<50 }
print(newarray)
let newarray1=array.filter { (x:Int) -> Bool in
return x % 2 == 0
}
print(newarray1)
//2.映射
let newarray2 = array.map {sqrt(Double($0))
}
print(newarray2)
//3.缩减.规约
let newarray3=array.reduce(0,combine:+)
print(newarray3)
let newarray4=array.reduce(1,combine:*)
print(newarray4)
let newarray5=array.reduce(array[0]){
$1 > $0 ? $1 : $0
}
print(newarray5)
let strarray = ["I","love","you"]
let result4 = strarray.reduce("", combine: +)
let result5 = strarray.reduce("") { $0 + " " + $1 }
print(result5)
两个排序结构要熟悉和掌握
冒泡排序
var array = [20,15,1,5,45,6,1,5,8,8,7,7,5,6]
for i in 0..array[j+1]
{
(array[j],array[j+1])=(array[j+1],array[j])
b = true
}
}
if b==false {
break
}
}
print(array)
简单选择排序
//简单选择顺序:每次从剩下的元素中找最小的元素放到对应的位置
var array = [4,21,45,4,6,4,8,4,6,54,3,45,5,4,1,2,5,8,8,9,5,5,4]
var minindex=0
for i in 0..
Day0808
课上知识点
字典(存放键值对组合的容器)
//字典(存放键值对组合的容器)
//字段中的每个元素都是由两部分组成的,冒号前面的是键冒号后面的是值
var dict:[String:String] = ["abacus":"suanpan","youbing":"shenjingb","haha":"王八蛋","haha2":"王八2蛋"]
//通过键获取对应的值(可控的类型,因为给的键可能没有与之对应的值)
//key ---> value
print(dict["haha"])
print(dict["haha"])
//添加元素
dict["yowei"] = "qunidayedexiaowangbaduzi"
//删除元素
dict.removeValueForKey("haha2")
dict["haha2"]=nil
//修改元素
dict["haha2"]="shabi"
//遍历元素
//遍历整个字典
for i in dict{
print(i)
}
//直接通过一个元组获得字典中的键和值
for (index,value) in dict{
print("\(index)--->\(value)")
}
函数
//函数的参数名在Swift中
//分了外部参数名和内部参数名 函数名(外部参数名 内部参数名:类型,外部参数名 内部参数名:类型)
//可以使用下划线来做外部参数名,那么这个外部参数名就被省略掉了
func mymin(a x:Int,b y:Int) ->Int{
return x < y ? x : y
}
//调用的时候要写外部参数名
print(mymin(a:3,b: 5))
定义函数
//func 函数名(参数列表) ->返回类型{函数执行体}
func sayHello (name:String,nannv:Bool = false//表示第二个参数有默认值
) ->String{
//
// let a = "hello,"+name+"!"
// //如果函数的返回类型不是VOID ,那么函数中一定有RETURN语句
// return a
if nannv {return "来吧,互相伤害,"+name+"!"
}else {
return "你好,小家伙"+name+"!"}
}
调用函数
//直接写函数的名字,然后传递参数就可以了
//调用Swift函数的时候,在默认情况下从第二个参数开始需要写参数名
print(sayHello("wangbadan",nannv:true))
//以下就是添加了默认值后的写法,如果没有给第二个参数赋值那么就直接使用默认值false
print(sayHello("HMP"))
参数可以是任意多个
//Swift中函数的参数列表可以是可变参数列表(参数的个数可以是任意多个)
func vari(a:Int...) ->Int {
var total=0
for num in a{
total+=num
}
return total
}
print(vari(90,8,87,56,456,3474))```
######同时函数也可以返回多个值
```swift
//可以使用元组让函数一次返回多条数据
func minMax(array: [Int]) -> (min: Int, max: Int)? {
if array.isEmpty{
return nil
}
var currentMin = array[0]
var currentMax = array[0]
for value in array[1.. currentMax {
currentMax = value
}
}
return (currentMin, currentMax)
}
if
let b=minMax([10,65,15,14,16,88,177,365]){
print(b.0)
print(b.1)
}
else {
print("请输入里面的东西啊啊啊!")}
输入输出函数inout
//inout 输入输出参数(不仅将数据传入函数还要从函数中取出数据)
//func creX(inout x:Int) ->Int{
// x = 1000
// return x
//}
//
//var x = 1
////inout 类型的参数前要加上&符号
// creX(&x)
//print(x)
函数的递归调用
//函数的递归调用(一个函数直接或间接的调用自身)
//1.需要递归公式
//2.收敛条件(什么时候就不需要调用函数了)
func factorial(n:Int) ->Double{
if n == 0 || n == 1{
return 1
}
return Double(n) * factorial(n - 1)
}
断言
//断言,就是一个判断语句,如果不满足将会显示下面的话在错误窗口
assert(m >= n,"m必须大于等于n")
代码综合运用
获取计算机当前时间模拟打招呼
func greeting(name:String) ->String{
let date = NSDate()
let cal = NSCalendar.currentCalendar()
- 获取计算机当前时间 精确到小时,也可以是分,秒
var hour=cal.component(.Hour, fromDate: date)
hour = 4
// if hour>=6&&hour<=10{
// print("早上好,"+name+"!")}
// else if hour>10&&hour<=14{
// print("中午好,"+name+"!")}
// else if hour>14&&hour<=20{
// print("下午好,"+name+"!")}
// else {
// print("晚上好,"+name+"!")}
// return name
var greeting:String
switch hour {
case 0...5:
//不同的分支可以有重叠的部分,按顺序来执行,执行了一个就不会执行下一个了
greeting="怎么还没睡呀,宝贝"
// fallthrough 继续执行下一个case
case 6...10:
greeting="真早,宝贝"
case 11...13:
greeting="吃午饭没,宝贝"
case 14...18:
greeting="下午过得怎么样,宝贝"
default:
greeting="睡觉了么,宝贝"
}
return name + "," + greeting + "!"
}
print(greeting("Baby"))
这是第几天?
//设计一个函数传入年月日返回这日期是这一年的第几天
func isLeapYear(year:Int) ->Bool{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0
}
func dayOfYear(year:Int, month:Int,day:Int) ->Int{
// var daysOfMonth=[31,28,31,30,31,30,31,31,30,31,30,31]
// if isLeapYear(year){
// daysOfMonth[1] = 29
// }
// var sum=0
// for i in 0..
用递归函数求1..N的和
////用递归函数计算1-N的和
//func sum(n:Int) ->Int{
// if n==1 {
// return 1
// }
// return n+sum(n-1)
//}
//print(sum(100))
哈诺伊塔问题
////哈诺伊塔问题
//var counter=0
//func han(n:Int,a:String,b:String,c:String){
// if n>0 {
// han(n-1, a: a, b: c, c: b)
// print("\(counter).\(a)--->\(b)")
// counter+=1
// han(n-1, a: c, b: b, c: a)
// }
//}
//print(han(5, a: "a", b: "b", c: "c"))
//
Day0809
课上知识点回顾
函数的特性
//swift中函数是一种类型
//这也意味着函数可以作为变量或常量的类型
//同理函数也可以作为另一个函数的参数或返回值
func foo(array:[Int],fn:(Int,Int)->Int) ->Int{
var sum=0
for i in array{
sum = fn(sum,i)
}
return sum
}
let a = [1,2,3,4,5]
//1.第二个参数可以传递自定义的函数(int,int) ->int
//2.可以传入二元运算符,也就是系统自带的函数 + - * / % (这些运算符也是函数)
闭包
传入匿名函数
print(foo(a, fn: sum))
print(foo(a, fn: +))
//完整的闭包写法
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){$0 + $1})
print(foo(a){ (a, b) -> Int in
return a+b})
```
######闭包函数的特性
```swift
var array = ["a","b","c","d321","e3213","f32131","av321","zer","mo"]
array.sortInPlace(<)
//如果函数的最后一个参数是闭包可以写成尾随闭包的形式
//也就是将闭包放到函数参数的圆括号外面写在一堆花括号中
//如果函数后面有尾随闭包切函数的圆括号中没有参数
//那么函数的圆括号也可以省略(仅限于有尾随闭包的场景)
array.sortInPlace { (one, two) -> Bool in
if one.characters.count==two.characters.count{
return one < two
}
return one.characters.count < two.characters.count
}
//array.sortInPlace{ $0 > $1}
print(array)
类
定义类:1
////如果苹果已经提供了你需要用的类,就不需要定义
////如果苹果原生是没有定义你需要的类,那就需要你定义
////定义类就可以创建出新的类型
////定义出学生类 就需要做以下的东西
class Student {
//数据抽象 - 找到和学生相关的属性(找名词,和学生相关的名词)
//变量定义到类的外面就叫变量 - value
//变量定义到类的里面就叫属性 - property
var name:String
var age:Int
//初始化方法(构造方法/构造器)-创建对象要使用的方法
init(name:String,age:Int){
self.name = name
self.age = age
}
//函数写在类的外面就叫函数 - function
//函数写在类的里面就叫方法 - method
//行为抽象 - 找到和学生相关的方法(找动词,和学生相关的动词)
func eat(foods:String) ->Void{
print("\(name)正在吃\(foods)")
}
func study(course:String) ->Void{
print("\(name)正在学习\(course)")
}
func watchJapaneseAv(){
if age >= 18{print("\(name)正在观看成人电影")
}else {
print("\(name)可以观看动画电影")
}
}
}
创建对象
//创建对象:2 (调用初始化的方法)
let stu1 = Student.init(name: "李连杰", age: 19)
//给对象发消息:3 (通过给对象发消息来解决问题)
stu1.eat("回锅肉")
stu1.study("《金瓶梅》")
stu1.watchJapaneseAv()
let stu2 = Student(name: "周星驰", age: 22)
stu2.eat("bB")
stu2.study("《感动中国的1千万个故事》")
stu2.watchJapaneseAv()
let stu3 = Student(name: "王八蛋", age: 16)
stu3.eat("木耳")
stu3.study("《中国最牛逼的男人---王八蛋》")
stu3.watchJapaneseAv()
枚举
- Get:枚举是定义符号常量的最佳方式
- GET:符号常量总是优于字面常量
枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合。
enum Gender {
case Male
case Female
}
这个枚举就包含了男女两个属性类型 就可以被调用了
代码综合应用
猜数字的类
class guessNum{
var c=0
func ternum(youNumber:Int) ->Bool{
var counter=false
c+=1
if youNumber>answer{
print("大了")
}
else if youNumber
Day0810
课上知识点回顾
类的特性
// 0. 发现类
// - 在对问题的描述中找名词和动词
// - 名词会成为类或者类中的属性 动词会成为类中的方法
// 1. 定义类
// - 数据抽象(属性)
// - 行为抽象(方法)
// - 初始化方法
// 访问修饰符
// - public (公开)
// - internal (内部的) - 默认
// - private (私有)
stored property存储属性(保存和圆相关的数据的属性)
var center: Point
var radius: Double
初始化方法
init(center: Point, radius: Double) {
self.center = center
self.radius = radius
}
```
######计算属性
- 通常获得某个计算出的值的方法都可以设计成计算属性
- computational property
- 计算属性(通过对存储属性做运算得到的属性)
```swift
var perimeter: Double {
// 圆的周长是一个只读属性
// 所以此处只有get{}没有set{}
get { return 2 * M_PI * radius }
}
便利构造器
- 我们可以在一个类中定义多个初始化方法
- 便利初始化方法 / 便利构造器
- 调用了其他的初始化方法的初始化方法
convenience init() { self.init(x: 0, y: 0) } convenience init(point: (Double, Double)) { self.init(x: point.0, y: point.1) }
######指派构造器
- 指派初始化方法 / 指派构造器
- 被其他初始化方法调用的初始化方法
```swift
init(x: Double, y: Double) {
self.x = x
self.y = y
}
```
#####生成指定范围内的随机数
```swift
func randomInt(min: UInt32, _ max: UInt32) -> Int {
return Int(arc4random_uniform(max - min + 1) + min)
}
代码综合应用
奥特曼打小怪兽
main中的代码
//判断小怪兽是否还活着,然后找出活着的
func pickOneMonster(marray:[Monster]) ->Monster{
var monster:Monster
repeat{
let randomIndex = randomInt(0, UInt32(marray.count-1))
monster = marray[randomIndex]
}while !monster.isAlive
return monster
}
let u = Ultraman(name: "王大锤", hp: 500, mp: 80)
let marray = [Monster(name: "熊丹凌", hp: 120),
Monster(name: "wotian", hp: 250),
Monster(name: "haha", hp: 180),
Monster(name: "hehe", hp: 120)
]
//判断小怪兽是否死光了
func isAllDead(marray:[Monster]) ->Bool{
for monster in marray{
if monster.isAlive{
return false
}
}
return true
}
var round = 1
repeat {
print("========第\(round)回合========")
let m = pickOneMonster(marray)
let factor = randomInt(1, 10)
switch factor{
case 1...7:
print("\(u.name)对\(m.name)使出了普通攻击")
u.attack(m)
if m.isAlive {
m.attack(u)
}
case 8...9:
print("\(u.name)对\(m.name)使出了吞天湿地")
if u.magicalAttack(marray){
for m in marray{
if m.isAlive{
m.attack(u)
}
}
}else{
u.attack(m)
if m.isAlive {
m.attack(u)
}
}
default:
print("\(u.name)对怪兽们使出了大招")
u.hugeAttack(m)
}
if m.isAlive {
m.attack(u)
}
print("\(u.name)奥特曼生命值: \(u.hp)")
print("\(u.name)奥特曼魔法值: \(u.mp)")
for m in marray{
print("\(m.name)小怪兽生命值: \(m.hp)")
}
round += 1
} while u.isAlive && !isAllDead(marray)
if u.isAlive {
print("\(u.name)奥特曼获胜!!!")
}
else {
print("小怪兽获胜!!!")
}
Uitraman中的代码
class Ultraman {
private var _name: String
private var _hp: Int
private var _mp: Int
var isAlive: Bool {
get { return _hp > 0 }
}
var name: String {
get { return _name }
}
var hp: Int {
get { return _hp }
set { _hp = newValue > 0 ? newValue : 0 }
}
var mp: Int {
get { return _mp }
}
init(name: String, hp: Int, mp: Int) {
_name = name
_hp = hp
_mp = mp
}
func attack(monster: Monster) {
let injury = randomInt(15, 20)
monster.hp -= injury
_mp = _mp+5>100 ? 100 : _mp+5
}
func hugeAttack(monster: Monster) {
let injury = monster.hp * 3 / 4 >= 50 ? monster.hp*3/4:50
monster.hp-=injury
}
func magicalAttack(monsters: [Monster]) ->Bool {
if _mp>=30{
for monster in monsters{
if monster.isAlive {
monster.hp -= randomInt(5, 15)
}
}
_mp -= 30
return true
}
return false
}
}
Monster的代码
class Monster {
private var _name: String
private var _hp: Int
var isAlive: Bool {
get { return _hp > 0 }
}
var name: String {
get { return _name }
}
var hp: Int {
get { return _hp }
set { _hp = newValue > 0 ? newValue : 0 }
}
init(name: String, hp: Int) {
_name = name
_hp = hp
}
func attack(ultraman: Ultraman) {
let injury = randomInt(5, 10)
ultraman.hp -= injury
}
}
Day0811
课上知识点回顾
类的一般特性
- 存储属性通常是PRIVATE的 因为要把数据保护起来
- 方法一般是PUBLIC的 因为方法是对象接受的消息
- 如果自定义的类没有打算在其他项目中使用 可以不写访问修饰符
- 直接使用默认的INTERNAL修饰符表示在本项目中公开对其他项目私有
运算符的重载
在Swift中很多时候对于一些运算符可以给它自定义一个功能函数,这个就是运算符的重载
//运算符重载,为自定义的类型定义运算符
func +(one:fraction,two:fraction) ->fraction{
return one.add(two)
}
func -(one:fraction,two:fraction) ->fraction{
return one.sub(two)
}
func *(one:fraction,two:fraction) ->fraction{
return one.cheng(two)
}
func /(one:fraction,two:fraction) ->fraction{
return one.chu(two)
}
短除法
- 短除法(欧几里得算法)
- x和Y的最大公约数跟y%x和 x的最大公约数是一样
func gcd(a:Int,b:Int) ->Int{
if a>b{
return gcd(b, b: a)
}else if b%a != 0 {
return gcd(b%a, b: a)
}
else{
return a
}
}
```
#####私有化类中的属性标签
在类中一般将定义的存储属性设置为私有Private.这样就可以防止数据被窜改,一般在标签前面加一个_
```swift
private var _name:String
private var _age:Int
数据私有后的传值
这里面只有GET获取数据,不能修改,因为已经私有了
var age:Int{
get {
return _age
}
}
去除字符串中的字
///姓名隐去最后一个字符
var name:String{
get{
//去除字符串的前几个字 除了最后一个
let displayName = _name.substringToIndex(_name.endIndex.advancedBy(-1))
return displayName+"*"
}
}
文档注释
/**
初始化方法
- parameter suite :花色
- parameter face :点数
*/
代码综合应用
扑克游戏
main.swift
func showPlayerCards(player:Player){
print("\(player.nickname)",terminator:":")
player.sortCards()
for card in player.cardsOnHand{
print(card.info,terminator:" ")
}
print("")
}
//扑克游戏
let p = Poker()
p.shuffle()
let p1 = [Player(nickname: "王八蛋"),Player(nickname: "李连杰")]
for _ in 1...2{
for player in p1{
if p.hasMoreCards{
player.getOneCad(p.deal()!)
}
}
}
for player in p1{
showPlayerCards(player)
}
var istrue = true
while istrue {
print("还要么?(1=要,2=不要)")
let a = inputInt()
var b=p1[0].add(p1[0].cardsOnHand)
var c=p1[1].add(p1[1].cardsOnHand)
if a == 1{
if p.hasMoreCards{
p1[0].getOneCad(p.deal()!)
if b>22||c==21||b==c{
print("\(p1[1].nickname)赢了1")
}else if b<=21 {
if c<=18 {
if p.hasMoreCards{
p1[1].getOneCad(p.deal()!)
}
if c>=22 || (b == 21 && c != 21) {
print("\(p1[0].nickname)赢了4")
}
}
}
else if c>21{
print("\(p1[1].nickname)赢了1")
}
}
}
else if a == 2 {
while c<=18 {
if p.hasMoreCards{
p1[1].getOneCad(p.deal()!)
if (b == 21 && c != 21) {
print("\(p1[0].nickname)赢了2")
}else if c>=22{
print("\(p1[0].nickname)赢了5")
}else if c>b && c<22{
print("\(p1[1].nickname)赢了6")
break
}
else if c==21 || c==b {
print("\(p1[1].nickname)赢了3")
}
}
}
if c>18&&c<22&&c>=b{
print("\(p1[1].nickname)赢了8")
}
}
if c == b {
print("\(p1[1].nickname)赢了9")
}
for player in p1{
showPlayerCards(player)
}
}
Card.swift
//Get:枚举是定义符号常量的最佳方式
//GET:符号常量总是优于字面常量
/**
花色的枚举
- Spade: 黑桃
- Hearth: 红心
- Club: 草花
- Diamond: 方块
*/
enum Suite:String{
case Spade = "♠️"
case Heart = "❤️"
case Club = "♣️"
case Diamond = "♦️"
}
///一张牌
class Card {
var suite:Suite
var face:Int
/**
初始化方法
- parameter suite :花色
- parameter face :点数
*/
init(suite:Suite,face:Int){
self.suite=suite
self.face=face
}
var info:String{
get{
var str = suite.rawValue
switch face{
case 1: str+="A"
case 11:str+="J"
case 12:str+="Q"
case 13:str+="K"
default:str+="\(face)"
}
return str
}
}
}
Poker.swift
func randomInt(min:Int, _ max:Int) ->Int{
//生成指定范围的随机数
return Int(arc4random_uniform(UInt32(max - min + 1)))+min
}
class Poker {
var i = 1
var cardsArray:[Card]=[]
/**
初始化方法,洗牌
*/
init(){
reset()
}
func reset(){
//先删掉剩下的牌
cardsArray.removeAll()
let suites = [Suite.Spade,Suite.Heart,Suite.Club,Suite.Diamond]
for suite in suites{
for face in 1...13{
let card = Card(suite: suite, face: face)
cardsArray.append(card)
}
}
}
func shuffle(){
//洗牌之前先重置所有的牌
reset()
//通过随机乱序的方式打乱牌的位置
for i in 0..Card? {
if hasMoreCards {
return cardsArray.removeFirst()
}
else{
return nil
}
}
var hasMoreCards:Bool{
get{return cardsArray.count > 0}
}
}
Player.swift
func <(one:Card,two:Card) ->Bool{
return one.faceInt{
var sum=0
for i in 0...card.count-1{
sum += card[i].face
}
return sum
}
}
Day0812
课上知识点回顾
继承
Student 和 teacher 都是人 都有人的基本属性,所以他们可以继承人拥有的基本属性,同时也有自己独特的属性,例如学习和教书
- 我们可以将子类型的对象复制给父类型的变量(因为子类跟父类之间是IS-A的关系)
- 学生是人老师也是人,所以学生和老师的对象可以赋值给人类型的变量
示例代码
main.swift
let p1 = person(name: "2", age: 25, gender: .Male)
//我们可以将子类型的对象复制给父类型的变量(因为子类跟父类之间是IS-A的关系)
//学生是人老师也是人,所以学生和老师的对象可以赋值给人类型的变量
p1.eat("shift")
let stu1:person = Student(name: "1", age: 18, major: "外氨基酸", gender: .Female)
//如果要将父类型的变量转换成子类型的时候,需要用AS运算符进行类型转换
//如果能够确认父类型的变量中就是某种子类型的对象可以用AS!进行转换
(stu1 as! Student).study("lishi")
//如果不确定父类型的变量中是哪种子类型,可以用AS?尝试转换
//继承的意义在于子类可以复制利用父类的代码并且增强系统现有的功能
if let temp = stu1 as? Teacher{
temp.teach("飒飒")
}
else {
print("\(stu1.name)不是老师111!!")
}
stu1.eat("屎")
let t = Teacher(name: "3", age: 39, gender: .Male, title: "傻逼")
t.eat("屎")
t.teach("问问企鹅去")
子类在父类的基础上表现子类的特征
- 继承:从已有的类创建新的类的过程,提供继承信息的称为父类(超类/基类)
- 得到继承信息的称为子类(派生类/衍生类)
- 通常子类除了得到父类的继承信息还会增加一些自己特有的东西
- 所以子类的能力一定比父类更强大
- 如果要将父类型的变量转换成子类型的时候,需要用AS运算符进行类型转换
- 如果能够确认父类型的变量中就是某种子类型的对象可以用AS!进行转换
- (stu1 as! Student).study("lishi")
- 如果不确定父类型的变量中是哪种子类型,可以用AS?尝试转换
- 继承的意义在于子类可以复制利用父类的代码并且增强系统现有的功能
if let temp = stu1 as? Teacher{
temp.teach("飒飒")
}
else {
print("\(stu1.name)不是老师111!!")
}
person中的代码
person 作为父类,包含了人所有的基本属性
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(food:String){
print("\(name)正在吃\(food)")
}
}
student中的代码
在CLASS student 后面添加:再加上父类的名字 就实现了继承
那么父类中的属性,子类就可以不需要写了
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 == .Male ? "他":"她")\(name)正在学习\(coursename)")
}
}
Teacher 中的代码
class Teacher:person{
var title:String
init(name:String,age:Int,gender:Gender,title:String){
self.title=title
super.init(name: name, age: age, gender: gender)
}
func teach(coursename:String) {
print("\(gender == .Male ? "他":"她")\(name)\(title)正在教\(coursename)")
}
}
多态
同样对象类型(Pet类型)接受相同的消息(调用相同的方法)
但是做了不一样的事情
实现多态的关键步骤:
1.方法重写(自乐在继承父类的过程中对父类已有的方法进行重写,而 且不同的子类给出各自不同的实现版本)
2.对象造型(将子类对象当成父类型来使用)
for pet in petsArray{
pet.play()
//同样对象类型(Pet类型)接受相同的消息(调用相同的方法)
//但是做了不一样的事情
//实现多态的关键步骤:
//1.方法重写(自乐在继承父类的过程中对父类已有的方法进行重写,而且不同的子类给出各自不同的实现版本)
//2.对象造型(将子类对象当成父类型来使用)
pet.shout()
pet.eat()
if let dog = pet as? dog{
dog.watchDoor()
}else if let cat = pet as? cat{
cat.catchTheMouse()
}else if let wangba = pet as? wangba{
wangba.move()
}
}
方法重写
父类有的方法 子类可以重新实现 这个操作叫做方法重写
需要在方法前 添加OveRVIDE关键字
重写有时也被称为置换、覆盖、覆写
override func shout() {
print("\(nickename):汪汪汪...")
}
override func play() {
super.play()
print("\(nickename):正在玩JB")
}
终极原则:高内聚,低耦合
面向对象七原则
1.单一职责原则(SRP)
2.开闭原则(OCP)
3.依赖倒转原则(面向对象编程,DIP)
依赖倒转原则(面向对象编程)
定义方法参数类型的时候尽可能使用父类型(抽象类型)
因为如果用父类型的参数调用方法时可以传入任意子类型对象
4里氏替换原则(LSP) 能用父类型地方就一定可以使用子类型
5.接口隔离原则(ISP)
6.合成聚合服用原则(CARP)
7.迪米特法则(LoD)
GOF设计模式--23种设计模式
代码综合应用
工资结算模拟
main.swift
let empsArray = [
Manager(name:"王大锤"),
Praogramer(name:"罗浩"),
Praogramer(name:"雨婷"),
Salesman(name:"广告衫"),
Salesman(name:"欧阳坚"),
Praogramer(name:"周鸿祎")
]
for emp in empsArray{
if let worker = emp as? Praogramer{
print("请输入\(worker.name)本月工作时间:",terminator:"")
worker.workingHour=inputInt()
}else if let worker = emp as? Salesman {
print("请输入\(worker.name)本月销售额:",terminator:"")
worker.sales = inputDouble()
}
print("\(emp.name)本月工资:\(emp.salary)元")
}
Employees.swift
class Employees{
var name:String
init(name:String){
self.name=name
}
var salary:Double{
get{
return 0
}
}
}
Manager.swift
class Manager:Employees {
override var salary: Double{
get {return 12000}
}
}
Salesman.swift
class Salesman:Employees {
var sales = 0.0
override var salary:Double{
get{ return 1000+0.5*sales }
}
}
Programer.swift
class Praogramer:Employees {
var workingHour = 0
override var salary:Double{
get{return 200*Double(workingHour)}
}
}