在上一个笔记中,学习了类和对象的相关知识。这个章节来说一说面向对象。在学习面向对象的语言中,不得不提面向对象的三大特征——封装、继承、多态。
1. 封装
根据职责将属性和方法封装到一个抽象的类中。
下面将用示例来说明:(类与类直接可以空两行)
示例一:
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):
'''Python能够自动将一对括号内部的代码连接在一起'''
return ("户型:%s]\n总面积:%.2f]\n添加的家具是:%s\n剩余:%.2f\n"
%(self.house_type,self.area,
self.item_list,self.free_area))
def add_item(self,item):
'''添加家具
1.判断家具的面积是否超过剩余面积,如果超过提示不能添加这件家具
2.将家具的名称追加到家具名称列表中
3.用房子的剩余面积-家具面积'''
if item.area >= self.area:
print("%s的面积太大,无法添加" %item.name)
self.item_list.append(item.name)
self.free_area = self.area - item.area
print()
#1.创建家具
bed = HouseItem("席梦思",4)
chest = HouseItem("衣柜",2)
table = HouseItem("餐桌",1.5)
print(bed)
# 2.创建房子对象
new_house = House("两室一厅",80)
new_house.add_item(bed)
print(new_house)
小结:
主程序只负责创建房子对象和家具对象,
示例二:
描述:一个对象的属性可以是另外一个类创建的对象
需求:
士兵许三多有一把98k
士兵可以开火
枪能够发射子弹
枪装填子弹–增加子弹数量
首先提取类(名词):士兵类,枪类
假设每一个新兵都没有枪,定义没有初始值的属性。设置为None
class Gun(object):
def __init__(self,model,):
"""枪的初始化
:param model: 枪的型号
"""
self.model = model
# 子弹的数量
self.bullet_count = 0
def add_bullet(self,count):
'''添加子弹'''
print("可以添加子弹")
self.bullet_count += count
def shoot(self):
# 1.判断子弹数量
if self.bullet_count <= 0:
print("[%s]没有子弹了"%self.model)
return
# 2.发射子弹
self.bullet_count -= 1
# 3.提示发射信息
print("tutututututu")
class Soldier(object):
def __init__(self,name):
# 1.新兵的属性
self.name = name
# 2.加入新兵没有枪
self.gun = None
def fire(self):
'''士兵开火
1.判断是否有枪
2.喊一声口号
3.装填子弹
4.射击'''
if self.gun is None:
print("[%s]还没有枪。。。"%self.name)
return
print("冲啊")
self.gun.add_bullet(50)
self.gun.shoot()
print("士兵可以开火")
# 创建枪对象
new_gun = Gun("98k")
# new_gun.add_bullet(30)
# new_gun.shoot()
# 创建士兵
xsd = Soldier("许三多")
xsd.gun = new_gun #相当于有了一把枪
xsd.fire()
print(xsd.gun)
此处补充一个小知识点:
1. is 与 == 区别:
is 用于判断两个变量引用对象是否为同一个,
== 用于判断引用变量的值是否相等。
2. object 类
在定义类时,如果没有父类,建议统一继承object。
class 类名(object):
pass
2. 继承
实现代码的重用,相同的代码不需要重复的编写。
示例展示:
class Anima(object):
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
class Dog(Animal):
def bark(self):
print("汪汪叫")
wang = Dog()
wang.eat()
wang.run()
wang.drink()
wang.bark()
结果:
吃
跑
喝
汪汪叫
小结:Dog类是Animal类的派生类,Animal类是Dog类的基类
继承具有传递性。
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
class Dog(Animal):
def bark(self):
print("汪汪叫")
class XiaoTianQuan(Dog):
def fly(self):
print("会飞")
wang = XiaoTianQuan()
wang.eat()
wang.run()
wang.drink()
wang.bark()
wang.fly()
吃
跑
喝
汪汪叫
会飞
2.1 重写
在继承中,如果父类方法不能满足子类的需求,在子类中可以重写父类方法。(方法名相同,实现过程不同,且可以覆盖父类方法)
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
class Dog(Animal):
def bark(self):
print("汪汪叫")
class XiaoTianQuan(Dog):
def bark(self):
print("wangwangwnag-----")
def fly(self):
print("会飞")
wang = XiaoTianQuan()
wang.eat()
wang.run()
wang.drink()
wang.bark()
wang.fly()
结果:
吃
跑
喝
wangwangwnag-----
会飞
2.2 super()
在重写父类的方法时,希望原本的父类方法调用,在需要的位置使用super().父类方法,来调用父类方法的执行。
代码演示:
class Animal:
def eat(self):
print("吃")
def drink(self):
print("喝")
def run(self):
print("跑")
class Dog(Animal):
def bark(self):
print("汪汪叫")
class XiaoTianQuan(Dog):
def bark(self):
# 1.使用super().调用原本在父类中封装的方法
print("神犬的叫声")
super().bark()
def fly(self):
print("会飞")
wang = XiaoTianQuan()
wang.bark()
wang.fly()
神犬的叫声
汪汪叫
会飞
2.3 多继承
子类可以拥有多个父类,并且具有所有父类的属性和方法。
格式:
class 子类名(父类名1,父类名2):
pass
在多继承中,应避免父类1和父类2中存在相同的方法。
代码演示:
class A:
def demo1(self):
print("AAAA---demo1")
def demo2(self):
print("AAAA---demo2")
class B():
def demo2(self):
print("BBB---demo2")
def demo3(self):
print("BBB----demo3")
class C(B,A):
pass
#当创建对象时,调用demo2(),则先调用B类中的方法。调用的时候哪个在前面就先调用哪个
c = C()
c.demo2()
# 可以使用__mro__,输出调用的顺序。
print(C.__mro__)
结果如下:
BBB---demo2
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
注意:
Python中MRO(Method resolution order)----方法搜索顺序。从左到右的顺序查找
print(C.__mro__)
小结:
多继承可以让子类对象,同时具有多个父类的属性和方法
2.4 私有属性和私有方法
对于父类的私有属性和私有方法的调用,我们将在下节笔记中详细讲述。
多态
不同的对象调用相同的方法,产生不同的执行结果,以继承和重写父类方法为前提,可以增加代码的灵活度。
代码演示:
class Dog(object):
def __init__(self,name):
self.name = name
def game(self):
print("%s在玩耍"%self.name)
class XiaoTianQuan(Dog):
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 和 %s玩耍"%(self.name,dog.name))
dog.game()
# 1.创建一个狗对象
#wangcai = Dog("旺财")
wangcai = XiaoTianQuan("会飞的旺财")
# 2.创建一个小明对象
xiaoming = Person("小明")
xiaoming.game_with_dog(wangcai)
哈哈!您已成功了一大半。