⾯向对象三⼤特征: 封装, 继承, 多态. 只要是⾯向对象编程语言. 都有这三个特征.
- 封装: 把很多数据封装到一个对象中. 把固定功能的代码封装到一个代码块, 函数, 对 象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了了⼀个很牛B的函数. 那这个也可以被称为封装. 在⾯向对象思想中. 是把⼀些看似⽆关紧要的内容 组合到一起统一进行存储和使用. 这就是封装.
- 继承: ⼦类可以自动拥有父类中除了私有属性外的其他所有内容. 说⽩了, ⼉子可以 随便用爹的东西. 但是朋友们, ⼀定要认清楚一个事情. 必须先有爹, 后有儿⼦. 顺序不能乱, 在python中实现继承非常简单. 在声明类的时候, 在类名后面添加一个⼩括号,就可以完成继承关系. 那么什么情况可以使用继承呢? 单纯的从代码层面上来看. 两个类具有相同的功能或者特征的时候. 可以采⽤继承的形式. 提取⼀个⽗类, 这个父类中编写着两个类相同的部分. 然后两个类分别取继承这个类就可以了了. 这样写的好处 是我们可以避免写很多重复的功能和代码. 如果从语义中去分析的话. 会简单很多. 如 果语境中出现了x是一种y. 这时, y是一种泛化的概念念. x比y更加具体. 那这时x就是y的子类. 比如. 猫是一种动物. 猫继承动物. 动物能动. 猫也能动. 这时猫在创建的时候就有了动物的"动"这个属性. 再比如, ⽩骨精是一个妖怪. 妖怪天生就有一个比较不好的功能叫"吃人", ⽩骨精一出生就知道如何"吃人". 此时白骨精继承妖精. 话不多说.上代码.
class Yao:
def chi(self):
print("我是妖怪, 我天⽣生就会吃⼈人")
class BaiGuJing(Yao): # 白骨精继承妖怪
pass
bgj = BaiGuJing()
bgj.chi() # 我是妖怪, 我天⽣就会吃⼈ # 虽然⽩骨精类中没有编写chi. 但是他爹有啊. 直接拿来用
在python中, ⼀个类可以同时继承多个父类. 说⽩了, 现在一个儿⼦可能会有多个爹了.既然是有这么多个爹, 总得有远有近. 比如. 有一个这样的牛B的⼈物, 叫锅不美. 就有很多个爹嘛.
class QinDie:
def chi(self):
print("亲爹给你好吃的")
def play(self):
print("亲爹会陪你玩")
class GanDie:
def qian(self):
print("⼲爹给钱啊")
def play(self):
print("⼲爹会陪你玩")
class GuNiang(QinDie, GanDie):
pass
bumei = GuNiang()
bumei.chi()# 亲爹
bumei.qian()# 亲爹没有, 找干爹
bumei.play()# 亲爹有了, 就不找干爹了
结果:
亲爹给你好吃的
⼲干爹给钱啊
亲爹会陪你玩
具体的MRO(method resolution order)算法. 我们到后面会具体进行分析和讲解.
3. 多态:同一个对象,多种形态.这个在python中其实是很不容易说明白的.因为我们⼀ 直在用. 只是没有具体的说. 比如. 我们创建一个变量a = 10 , 我们知道此时a是整数 类型. 但是我们可以通过程序让a = "alex", 这时, a⼜变成了字符串类型. 这是我们都 知道的. 但是, 我要告诉你的是. 这个就是多态性. 同一个变量a可以是多种形态. 可能 这样的程序和说法你还get不到具体什么是多态. 接下来. 我们来看一个程序. 北京动 物园饲养员alex一天的工作. 从早上开始喂养猪, 中午喂哈士奇, 晚上还得喂阿拉斯加.
来我们⽤用代码实现这样的代码:
class Animal:
def chi(self):
print("动物就知道吃")
class Pig(Animal):
def chi(self):
print("猪在吃")
class Haski(Animal):
def chi(self):
print("哈⼠士奇在吃")
class Alasika(Animal):
def chi(self):
print("阿拉斯加在吃")
class SiYangYuan:
def yanng_animal(self, ani):
ani.chi()
zhu = Pig()
erha = Haski()
ala = Alasika()
alex = SiYangYuan()
alex.yanng_animal(zhu)
alex.yanng_animal(erha)
alex.yanng_animal(ala)