1.面向对象的封装
封装:根据职责将属性和方法封装到一个抽象的类中
1.封装是面向对象编程的一大特点
2.面向对象编程的第一步,将属性和方法封装到一个抽象的类中
3.外界使用类创建对象,然后让对象调用方法
4.对象方法的细节都被封装在类的内部
如:
小明体重75.0公斤
小明每次跑步都会减肥0.5公斤
小明每次吃东西体重都会增加1公斤
class Person:
def __init__(self,name,weight):
self.name = name
self.weight = weight
def __str__(self):
return '我的名字是 %s 体重是 %.2f' %(self.name,self.weight)
def run(self):
print('%s 去跑步...' %(self.name))
self.weight -= 0.5
def eat(self):
print('%s 吃东西...' %(self.name))
self.weight += 1
xiaoming = Person('小明',75.0)
xiaoming.run()
print(xiaoming)
xiaoming.eat()
print(xiaoming)
例题1:
1.房子有户型,总面积和家具名称列表
新房子没有任何的家具
2.家具有名字和战地面积,其中
床:占4平米
衣柜:占2平面
餐桌:占1.5平米
3.将以上三件家具添加到房子中
4.打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表
做法:
```bash
class HouseItem: ##创建家具的类
def __init__(self,name,area):
self.name = name
self.area = area
def __str__(self):
return'[%s] 占 %.2f 平方' %(self.name,self.area)
class House: ##创建房子的类
def __init__(self,house_type,area):
self.house_type = house_type
self.area = area
self.free_area = area ##剩余面积,当没有家具时,总面积就是剩余面积
self.item_list = []
def __str__(self):
return('户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s'
%(self.house_type,self.area,self.free_area,self.item_list))
def add_item(self,item):
if item.area > self.free_area:
print('%s 的面积太大,无法添加' %(item.name))
return
self.item_list.append(item.name)
self.free_area -= item.area ##计算剩余面积
##创建家具对象
bed = HouseItem('bed',4)
print(bed)
chest = HouseItem('chest',2)
print(chest)
table = HouseItem('table',1.5)
print(table)
##创建房子的对象
home = House('两室一体',100)
home.add_item(bed)
home.add_item(chest)
home.add_item(table)
print(home)
例子2:
1.士兵瑞恩有一把AK47
2.士兵可以开火(士兵开火扣动的是扳机)
3.枪 能够 发射子弹(把子弹发射出去)
4.枪 能够 装填子弹 ---增加子弹的数量
做法:
class Gun(): ##枪的类
def __init__(self,mode):
self.mode = mode
self.bullet_count = 0
def add_bullet(self,count):
self.bullet_count += count
def shoot(self):
if self.bullet_count <=0:
print('%s没有子弹~~' %self.mode)
return
self.bullet_count -= 1
print('%s~~~~~%s' %(self.mode,self.bullet_count))
class Solder(): ##人的类
def __init__(self,name):
self.name = name
self.gun = None
def fire(self):
if self.gun == None:
print('%s 没枪....'%(self.name))
self.gun.add_bullet(10)
self.gun.shoot()
##枪的对象
gun = Gun('AK47')
# gun.add_bullet(0)
# gun.shoot()
##人的对象
solder = Solder('Ruien')
solder.gun = gun
solder.fire()
2、继承
1)继承:实现代码的复用,相同的代码不需要重复的写
子类继承父类,可以直接享用父类封装好的方法
子类可以根据自己特有,封装子类特有的属性和方法
如:
class Animal:
def eat(self):
print('eat')
def drink(self):
print('drink')
def sleep(self):
print('sleep')
class Cat(Animal): ##继承父类
def call(self):
print('~~~~~')
##创建对象
mao = Cat()
mao.eat()
mao.call()
2)继承是可以传递的,具有传递性
当父类方法的实现不能满足子类的需求时候,
可以对方法进行重写(覆盖父类的方法)
也可以对父类方法进行扩展补充
如:
class Animal:
def eat(self):
print('eat')
def drink(self):
print('drink')
def sleep(self):
print('sleep')
class Cat(Animal): ##继承父类
def call(self):
print('~~~~~')
class Hellokitty(Cat):
def call(self): ##对父类属性进行覆盖
print('hahah')
# Cat.call(self) ##python2中
super().call() ##python3中,调用原本在父类中封装的方法
##创建对象
mao = Hellokitty()
mao.eat()
mao.call()
3)当继承多个父类时候,按顺序继承
4)式类和旧式类(经典类)
object是python为所有对象提供的基类,提供一些内置的属性和方法(可以使用dir函数查看)
新式类:以object为基类,python3中
旧式类:不以object为基类,在python2版本中
定义类时候,如没有继承,应该写成如下格式:
class A(object):
这样代码在各版本环境中都可以运行
3、多态
1)多态(以封装和继承为前提)
不同的子类对象调用相同的方法,产生不同的执行结果
如:
class Dog(object):
def __init__(self,name):
self.name =name
def game(self):
print('%s 开心的玩耍' %(self.name))
class Gaofei(Dog):
"""父类不能满足子类需求,重写game的方法"""
def game(self):
print('%s 来妲己一起玩耍吧' %(self.name))
class Person(object):
def __init__(self,name):
self.name = name
def game_with_dog(self,dog):
print('%s and %s 玩 *** ' %(self.name,dog.name))
dog.game() ##等于说封装到类中
wangcai = Gaofei('wangcai') ##创建一个狗对象
xiaoming = Person('xiaoming') ##创建一个人对象
xiaoming.game_with_dog(wangcai) ##人和狗玩
2)类方法:针对类对象定义的方法 在类方法内部可以直接访问类属性或者调员工其他的类方法
类属性:针对类对象定义的属性 使用赋值语句在class关键字下可以定义类属性
类属性用于记录与这个类相关的特性
如:
class Toy(object):
#使用赋值语句定义类属性,记录所有玩具的数量
count=0
def __init__(self,name):
self.name = name
#让类属性 +1
Toy.count +=1
@classmethod
def show_toy_count(cls):
print('玩具数量 : %d' %(cls.count))
##创建玩具对象
toy1 = Toy('wa')
toy2 = Toy('ha')
toy3 = Toy('oo')
#调用类方法
Toy.show_toy_count()
3)静态方法:
在开发中,如果需要在一个类中封装一个方法 这个方法
既不需要访问实例属性或者调用实例方法
也不需要访问类属性或者调用类方法
这个时候,我们就可以把这个方法封装成一个镜头方法
如:
class Cat(object):
@staticmethod
def call():
print('wahaha')
Cat.call() #通过类名调用静态方法,不需要创建对象,直接就可以使用
例子:设计一个Game类
1.查看帮助信息
2.查看历史最高分
3.创建游戏对象,开始游戏
class Game(object):
top_score =10000
def __init__(self,name):
self.name =name
@classmethod
def show_high_score(cls):
print('记录: %d ' % (cls.top_score))
@staticmethod
def help():
print('help')
def start_game(self):
print( '%s play' %(self.name))
@staticmethod
def adduser():
print('add')
Game.help()
Game.show_high_score()
Game.adduser()
game = Game('wa')
game.start_game()
4)类的结构
术语–实例
1.使用面向对象开发,第一步是设计类
2.使用 类名() 创建对象,创建对象的动作有两步
1.在内存中为对象分配空间
2.调用初始化方法__init___ 为对象初始化
3.对象创建后,内存中就有了一个对象的实实在在的存在–实例
因此:
1.创建出来的对象叫做类的实例
2.创建对象的动作叫做实例化
3.对象的属性叫做实例属性
4.对象调用的方法叫做实例方法
在程序执行时:
1.对象各自拥有自己的实例属性
2.调用对象的方法,可以通过self
访问自己的属性
调用自己的方法
结论:
1.每一个对象都有自己独立的内存空间,保存各自不同的属性
2.多个对象的方法,在内存中之有一份,在调用方法时,需要把对象的引用传递到方法内部
5)私有属性和私有方法
应用场景及定义方式
应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象的内部使用,
而不希望在外部被访问到
私有属性 就是 对象 不希望公开的 属性
私有方法 就是 对象 不希望公开的 方法
定义方法
在定义属性或方法时,在属性名或者方法名前增加两个下划线,
定义的就是私有属性或方法
如:
class Women(object):
def __init__(self,name):
self.name = name
self.__age = 18 ##私有属性
def secure(self):
print(self.__age) ##可以被写如其他共有属性中访问
man = Women('haha')
print(man.name)
##print(man.__age) #外界不能直接访问
#私有属性和私有方法外界都不能直接访问
man.secure()