day07-面向对象
目录
一、特殊方法和参数#
1. 成员方法的self参数#
成员方法中self表示调用该方法的对象
对象调用⽅法时,python解释器会把这个对象作为第⼀个参数传递给⽅法 通过self也可以获取对象的属性,调用对象的其它成员方法.
class Person:
def __init__(self, name, age):
# 定义成员属性
self.name = name
self.age = age
def sayHello(self):
# 通过self访问成员属性
print(self.name)
# 对象
p = Person('张三', 30)
p.sayHello()
2. __init__方法#
init()是一个内置的方法 当对象创建的时候就会自动执行__init()方法
# 定义类
class Person:
def __init__(self):
print('执行了init方法')
# 创建对象
p1 = Person()
p2 = Person()
运行结果 一旦创建了该类的对象就会执行__init__方法
3. __str__方法#
__str__也是类的内置方法
用于将对象转化为适于人阅读的形式
先看一段代码:
class Person:
def __init__(self,name,age):
# 成员属性
self.name = name
self.age = age
# 创建对象
p1 = Person('张三',30)
p2 = Person('李四',40)
print(p1)
print(p2)
运行结果
创建了两个对象,输出两个对象
从结果中我们并不能区分出到底哪个是属于p1,哪个是属于p2
可以通过__str__提取对象的主要特征用于区分不同的对象
class Person:
def __init__(self,name,age):
# 成员属性
self.name = name
self.age = age
def __str__(self):
'''
以字符串输出对象,把对象变成我们能够读懂的形式输出出来
:return:
'''
return 'name:{},age:{}'.format(self.name,self.age)
# 创建对象
p1 = Person('张三',30)
p2 = Person('李四',40)
print(p1)
print(p2)
运行结果
我们从结果中很容易就区分出两个对象的不同。
二、面向对象手机案例#
需求:
手机电量默认是100
打游戏每次消耗电量10
听歌每次消耗电量5
打电话每次消耗电量4
接电话每次消耗电量3
充电可以为手机补充电量
要求:
定义手机类
定义手机类的属性和行为
创建手机对象,访问属性和行为
分析:
1.定义类手机类 MobilePhone
2.类具备属性 battery :100
3.定义方法playGame battery -= 10
4.listenMusic battery -= 5
5.call battery -= 4
6.receive battery -= 3
7.charge battery += 10
代码
#1定义类MobilePhone
class MobilePhone:
#2定义属性:电量battery
def __init__(self):
self.battery = 100
#3定义方法1:打游戏
def playGame(self):
# 电量是否满足打游戏的条件
if self.battery>=10:
print('打游戏')
# 消耗10个电量
self.battery -= 10
else:
print('电量不足,不能打游戏,需要充电!')
# 3定义方法2:听歌
def listenMusic(self):
if self.battery >= 5:
print('听歌')
# 消耗5个电量
self.battery -= 5
else:
print('电量不足,不能听歌,需要充电!')
# 3定义方法3:打电话
def call(self):
if self.battery >= 4:
print('打电话')
# 消耗4个电量
self.battery -= 4
else:
print('电量不足,不能打电话,需要充电!')
# 3定义方法4:接电话
def receiveCall(self):
if self.battery >= 3:
print('接电话')
# 消耗3个电量
self.battery -= 3
else:
print('电量不足,不能接电话,需要充电!')
# 3定义方法5:充电
def charge(self):
print('充电')
self.battery += 10
#判断
if self.battery>100:
self.battery=100
def __str__(self):
return '当前电量:{}'.format(self.battery)
# 定义手机对象
phone = MobilePhone()
print('初始状态',phone)
phone.playGame()
print(phone)
phone.listenMusic()
print(phone)
phone.call()
print(phone)
phone.receiveCall()
print(phone)
phone.charge()
print(phone)
三、搬家具案例#
1. 搬家具规则#
1.家具分不同的类型,并占用不同的面积
2.输出家具信息时,显示家具的类型和家具占用的面积
3.房子有自己的地址和占用的面积
4.房子可以添加家具,如果房子的剩余面积可以容纳家具,则提示家具添加成功;否则提示添加失败
5.输出房子信息时,可以显示房子的地址、占地面积、剩余面积
6.查看房子中所有的家具
2分析
类的设计#
可以提取两个类:家具类和房子类
每个类具备的属性和方法如下:
家具类:
1.使用 Item 类可以创建 家具对象
2.家具有两个属性:
家具类型 type:字符串
家具面积 area:整数
3.实现__str__方法
4.显示家具的 type 和 area 属性
房子类:
1.使用 Home 类可以创建 房子对象
2.房子有四个属性:
地址 address:字符串
房子面积 area:整数
房子剩余面积 free_area:整数,默认为房子的面积
家具列表 items:列表
3.实现__str__方法
显示房子的 address 、area、free_area 属性
4.实现add_item方法,提供item参数来添加家具
如果 可以容纳家具:
家具 加入 item属性
剩余面积 减少
如果 不能容纳家具: 提示家具添加失败
代码实现#
"""------------------ 家具类 ------------------"""
class Item:
def __init__(self,type,area):
'''
创建家具类的初始化方法
:param type: 家具类型
:param area: 家具面积
'''
self.type = type
self.area = area
def __str__(self):
return '家具类型:{},家具占用面积:{}'.format(self.type,self.area)
"""------------------ Home ------------------"""
class Home:
def __init__(self,address,area):
'''
房子的初始化方法
:param address: 房子地址
:param area: 房子面积
'''
self.address = address
self.area = area
# 剩余面积
self.free_area = self.area
# 家具列表
self.items = []
def __str__(self):
return '房子地址:{},占地面积:{},剩余面积:{}'.format(self.address,self.area,self.free_area)
def add_item(self,item):
'''
添加家具到房子中
:param item: 家具类Item的实例
:return:
'''
if self.free_area >= item.area:
# 家具添加到列表中
self.items.append(item)
# 修改剩余面积
self.free_area -= item.area
# 可以添加
print('添加成功')
else:
# 不能添加
print('面积不足,不能添加家具')
# 创建家具
item1 = Item('桌子',10)
item2 = Item('椅子',5)
# 创建房子
home = Home('汤臣一品',300)
# 打印家具
print(item1)
print(item2)
print(home)
"""------------------ 添加家具 ------------------"""
home.add_item(item1)
print(home)
print(home.items[0])
home.add_item(item2)
print(home)
print(home.items[0],home.items[1])
运行结果:
四、私有化#
将属性或者方法设置为不能在外部访问,就是私有化
私有化包括:属性私有化、方法私有化
私有化作用:保证类中数据安全
1. 属性私有化#
属性私有化格式: self.__属性名 = 属性值
代码
class Circle:
def __init__(self,radius):
# 半径
self.radius = radius
# 私有化圆周率属性
self.__PI = 3.1415926
def perimeter(self):
'''
求圆的周长
:return: 圆的周长
'''
return 2*self.__PI*self.radius
p=Circle(4)
a=p.perimeter()
print(a)
运行结果:
2. 方法私有化#
方法的私有化方式和属性私有化方式一样
class Person:
def sayHello(self):
print('hello')
p=Person()
p.sayHello()
五、面向对象三大特征#
面向对象三大特征是:封装、继承和多态
1. 封装#
封装就是隐藏内部实现的细节,只保留功能接口
封装的范围:
1.封装属性 2.封装成方法/函数 3.封装成类 4.封装模块和包
代码演示
在这里插入代码片
2. 继承#
继承指的是一个对象直接使用另一个对象的属性或方法
继承的格式: class 子类名(父类名): …
"""------------------ 定义Person类 ------------------"""
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def sayHello(self):
print('hello')
"""------------------ 定义Student类继承Person ------------------"""
class Student(Person):
def __init__(self,name,age,id):
super(Student, self).__init__(name,age)
self.id = id
# 创建学生类
stu = Student('小明',15,'123')
# 访问属性
print(stu.name,stu.age,stu.id)
# 调用方法
stu.sayHello()
运行结果
3. 多继承#
有多个父类的继承关系就称为多继承
多继承格式: class 子类(父类1,父类2…) …
Son继承了Mother和Father
可以调用多个父类中的方法
代码演示
# 定义Mother类,Mother具有cook方法
class Mother:
def cook(self):
print('做饭')
# 定义Father类,Father具有makeMoney方法
class Father:
def makeMoney(self):
print('赚钱')
# 定义Son类
class Son(Mother, Father):
pass
# 创建Son对象
son = Son()
# 调用Mother的功能
son.cook()
# 调用Father的功能
son.makeMoney()
运行结果
4. 多态#
多态指的是一类事物有多种形态(一个类有多个子类)
多态的概念依赖于继承
中国人、美国人、非洲人都是属于Human人类的子类
对于Human来说有多个子类就称为多态
# 父类
class Human:
def eat(self):
print('人类吃饭')
# 中国人
class ZhHuman(Human):
def eat(self):
print('中国人使用筷子吃饭')
# 美国人
class UsHuman(Human):
def eat(self):
print('美国人使用刀叉吃饭')
# 非洲人
class AfricaHuman(Human):
def eat(self):
print('非洲人直接用手吃恩希玛')
# 函数
def tranlate(human):
'''
接收一个具备吃放功能的Human对象
:param human:Human对象
:return:
'''
human.eat()
# 创建四个对象
human = Human()
zhHuman = ZhHuman()
usHuman = UsHuman()
africaHuamn = AfricaHuman()
# 调用translate方法
tranlate(human)
tranlate(zhHuman)
tranlate(usHuman)
tranlate(africaHuamn)
tranlate方法需要接收具备eat功能的Human对象,但是由于ZhHuman USHuman AfricaHuman都具备eat功能所以也可以传递到tranlate方法中
5. 鸭子模型#
一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟可以被称为鸭子“
对于上述的translate
class Dog:
def eat(self):
print('狗吃骨头')
# 函数
def tranlate(human):
'''
接收一个具备吃饭功能的Human对象
:param human:Human对象
:return:
'''
human.eat()
dog = Dog()
tranlate(dog)
translate需要传递一个Human,但是Dog也具备eat功能,所以也可以传递运行
这是由于python是动态类型语言,不能像java等静态类型语言一样,限制传递的数据类型
只要运行时发现dog对象有这个功能,就可以在函数中使用
六、反恐精英#
反恐精英是非常经典的游戏,游戏中分为两个角色:警察和土匪
警察和土匪都可以拿枪打击对方
我们要用面向对象实现反恐精英流程
1. 需求说明#
1.游戏枪支有不同的型号,并拥有不同的伤害
2.枪支可以添加一定数量的子弹
3.枪支可以设计敌人,设计敌人时,如果子弹数量为0,则提示玩家;如果有子弹,会减少子弹,如果击中敌人,会让敌人受伤
4.输出枪支信息时,可以显示枪支的型号、伤害、子弹数量
5.游戏玩家分为警察和土匪两种角色,玩家拥有自己的枪支和血量,可以攻击敌人
6.玩家攻击敌人时,如果没有枪,则提示玩家;如果有枪,则检查枪支是否有子弹,有子弹则使用枪支射击敌人,没有子弹则自动给枪支添加子弹
7.玩家被击中会受伤,减少血量为枪支的伤害,提示玩家受伤并显示当前血量;如果血量<=0,则提示玩家死亡
8.输出玩家信息时,可以显示玩家角色、状态、血量、所持有枪支的信息
枪支类
使用Gun类可以创建枪支对象
枪有三个属性:
型号:model
杀伤力:damage
子弹数量:bullet_count,默认没有子弹
实现__str__方法,显示枪的model、damage和area属性
调用add_bullets方法可以增加子弹数量
调用shoot方法可以给参数敌人对象造成伤害
如果没有子弹,则提示玩家并返回
如果有子弹,则:
子弹数量减少
调用敌人对象的hurt方法,给敌人造成伤害
玩家类
使用Player类可以创建警察对象和土匪对象
玩家有三个属性:
姓名:name
血量:hp
枪:gun 使用Gun类创建的对象,初始没有枪
实现__str__方法,显示玩家的name、hp和gun属性
调用hurt方法可以让当前玩家受到enemy_gun的伤害,具体流程如下:
玩家血量减去枪对象的damage伤害度
判断修改后的玩家血量
如果血量<0,提示玩家挂了
否则,提示玩家受伤以及当前血量
调用fire方法可以向enemy开火,具体流程如下:
判断自己是否有武器,如果没有直接返回
检查自己的枪是否有子弹,如果没有,自动装填子弹
让自己的枪调用shoot方法,并传递要射击的敌人对象
主程序流程
创建枪对象并测试装填和发射子弹
创建警察对象policeman和匪徒对象badman
将枪支交给警察,警察向匪徒开火
利用循环消灭匪徒
2. 代码实现#
"""------------------ 枪支类 ------------------"""
class Gun:
def __init__(self, model, damage):
#三个属性
self.model = model
self.damage = damage
# 默认子弹数量0
self.bullet_count = 0
#__str__方法显示枪支的型号、伤害、子弹数量
def __str__(self):
return '型号:{},伤害:{},子弹数量:{}'.format(self.model, self.damage, self.bullet_count)
def add_bullets(self, count):
'''
添加子弹
:param count:
:return:
'''
self.bullet_count += count
print('添加子弹成功')
def shoot(self, enemy):
'''
射击敌人
:param enemy: 敌方Player类型
:return:
'''
# 判断子弹是否为0
if self.bullet_count == 0:
print('请填充子弹')
else:
# 有子弹
# 减少子弹
self.bullet_count -= 1
# 默认击中敌人
enemy.hurt(self)
"""------------------ 游戏玩家类 ------------------"""
class Player:
def __init__(self, role):
'''
初始化玩家
:param role: 玩家角色
'''
self.role = role
# 默认血量为100
self.hp = 100
# 枪支 默认没有枪支 为None
self.gun = None
# 状态
self.state = '活着'
def __str__(self):
return '角色:{},状态:{},血量:{},枪支:{}'.format(self.role, self.state, self.hp, self.gun)
def fire(self, enemy):
'''
射击敌人
:param enemy: 敌人Player类型
:return:
'''
# 判断有没有枪
if self.gun:
# 有枪
# 判断是否有子弹
if self.gun.bullet_count > 0:
# 有子弹
self.gun.shoot(enemy)
else:
# 没有子弹,添加子弹
self.gun.add_bullets(5)
else:
# 没枪
print('现在还没有枪支')
def hurt(self, enemy_gun):
'''
玩家受到伤害
:param enemy_gun:受到哪个枪支的伤害
:return:
'''
# 减少血量
self.hp -= enemy_gun.damage
if self.hp<=0:
# 死亡
print('玩家:{}死亡'.format(self.role))
else:
# 提示玩家受伤 提示当前血量
print('玩家受伤,当前血量:{}'.format(self.hp))
"""------------------ 主流程 ------------------"""
# 创建枪支
gun = Gun('ak47',10)
# 创建警察
policeman = Player('警察')
# 创建土匪
badman = Player('土匪')
# 把枪支交给警察
policeman.gun = gun
# 警察射击土匪
while badman.hp>0:
policeman.fire(badman)
运行结果