上一期文章给大家介绍了Python中如何使用类和常用的魔法函数。感兴趣的伙伴可以前往阅读。本期文章主要介绍一下面向对象的三大特征:封装、继承和多态。因为Python是一门面向对象(也是面向过程)的语言,所以小编和大家聊一下在Python语言中三大特征是如何实现的。看官,let’s go!
一、封装
封装简单说就是隐藏对象的属性和实现细节(方法), 仅对外提供公共的访问方式。那它有什么好处呢?首先封装通过私有化提高了代码的安全性,通过内部的函数提高了代码的可复用性。当然了提高安全性的代价就是增加了公共的访问方式代码的编写使代码量增加了。
提到封装不得不学会它的私有化。如果父类的成员不想被子类直接继承(或者重写, 修改等), 但是还想给子类用, 就可以考虑用私有化。
格式如下:
__属性名 # 注意: 这里是 两个_
__函数名() # 注意: 这里是 两个
代码如下:
# 1. 定义一个父类, 有自己的属性 和 行为.
class father(object):
# 1.1 属性
def __init__(self):
self.kongfu = '[独创的蛋炒饭配方]'
# 私有的属性.
self.__money = 100000000 # 不要数了,1个小*标。
# 1.2 对外提供公共的访问方式, 可以实现: 获取私有的变量, 以及给变量设置值.
# 获取值.
def get_money(self):
return self.__money
# 设置值
def set_money(self, money):
self.__money = money
# 1.3 行为
def __make_cake(self):
print(f'采用 {self.kongfu} 制作炒饭!')
# 可以验证: 私有成员, 在本类中是可以直接访问的.
print(f'私房钱为: {self.__money}')
# 针对于父类的私有方法, 提供公共的访问方式(在其内部调用 私有化的方法即可)
def my_make(self):
# 调用私有化方法 __make_cake()
self.__make_cake()
# 2. 定义子类, 继承自上面父类.
class son(father):
pass
# 在main函数中测试调用
if __name__ == '__main__':
# 3. 创建子类对象.
s = son()
# 4. 尝试访问父类的成员.
# 4.1 父类的 私有的 属性.
print(f'父类的私有属性, 通过 公共的方式访问: {s.get_money()}')
# 通过父类的公共方式, 修改 父类的私有属性.
s.set_money(10)
# 再次打印
print(f'父类的私有属性, 通过 公共的方式访问: {s.get_money()}')
# 4.2 父类的 私有的 方法(行为).
s.my_make()
二、继承
实际开发中我们发现多个类中的内容是相似的或者相同的每次写很麻烦,。针对于这种情况, 我们可以把这些相似的或者相同的内容抽取出来, 单独的放到1个类中(父类), 然后让那多个类(子类)和这个类产生关系, 这个关系就叫继承。
继承的好处是可以提高代码的复用性和可维护性。当然了导致的弊端就是耦合性增强了,那如何解耦合呢?就用到了多态。这里我们先说继承。
2.1单继承
格式如下:
class father(object):
pass
class son(father):
pass
代码如下:
# 创建一个动物基类
class Animal(object):
# 定义run函数
def run(self):
print('跑起来...')
# 定义一个马类,继承动物基类
class Horse(Animal):
# 定义run和eat方法
def run(self):
print('乌拉乌拉。。。迈着矫健的步伐跑起来!!')
def eat(self):
print('可以吃东西...')
if __name__ == '__main__':
# 测试调用
ma = Horse()
ma.run()
ma.eat()
2.2 多继承
格式如下:
class father1(object):
pass
class father2(object):
pass
class son(father1, father2):
pass
代码如下:
# 1. 创建1个师傅类, 充当父类.
class Master(object):
# 1.1 定义父类的 属性.
def __init__(self):
self.kongfu = '[传统工艺蛋炒饭配方]'
self.name = 'Master'
# 1.2 定义父类的 行为, 表示: 炒蛋炒饭.
def make_cake(self):
print(f'使用 {self.kongfu} 制作蛋炒饭')
# 2. 创建另一个类, 充当第2个父类.
class School(object):
# 2.1 定义父类的 属性.
def __init__(self):
self.kongfu = '[蓝*蛋炒饭配方]'
# 2.2 定义父类的 行为, 表示: 炒蛋炒饭.
def make_cake(self):
print(f'使用 {self.kongfu} 制作蛋炒饭')
# 3. 定义徒弟类, 继承自师傅类.
class Prentice(School, Master):
pass
# 在main函数中测试
if __name__ == '__main__':
# 4. 创建子类的对象
p = Prentice()
# 5. 尝试打印 p对象的 属性 和 行为
print(f'从父类继承的属性: {p.kongfu}')
p.make_cake() # 从父类继承来的行为.
# 温馨提示:
# 1. 多个父类有重名的成员, 优先用第1个父类的。
# 2. 某个成员, 子父类都有, 优先用 子类的。
2.3 多层继承
理解格式如下:
A => 继承B => 继承 C=>object
代码如下:
# 创建一个动物基类
class Animal(object):
# 定义run方法
def run(self):
print('跑起来...')
# 定义 马类 继承动物基类
class Horse(Animal):
def eat(self):
print('可以吃东西...')
# 定义千里马类,继承马类
class SwiftHorse(Horse):
def __init__(self):
# 初始化名字
self.name = '千里马'
# 定义吃函数
def eat(self):
print('一天可以吃一担粮食...')
if __name__ == '__main__':
# 测试调用
sh = SwiftHorse()
print(sh.name)
sh.run()
sh.eat()
2.4 方法重写
子类出现和父类一模一样的 属性 或者 方法时, 称之为: 重写, 也叫覆盖。大多数涉及到的是方法重写。
代码如下:
# 哈哈哈 还得是蛋炒饭 哈哈哈哈哈哈
# 1. 创建1个师傅类, 充当父类.
class Master(object):
# 1.1 定义父类的 属性.
def __init__(self):
self.kongfu = '[传统工艺蛋炒饭配方]'
self.name = 'Master'
# 1.2 定义父类的 行为, 表示: 炒蛋炒饭.
def make_cake(self):
print(f'使用 {self.kongfu} 制作蛋炒饭')
# 2. 创建另一个类, 充当第2个父类.
class School(object):
# 2.1 定义父类的 属性.
def __init__(self):
self.kongfu = '[蓝*蛋炒饭配方]'
# 2.2 定义父类的 行为, 表示: 炒蛋炒饭.
def make_cake(self):
print(f'使用 {self.kongfu} 制作蛋炒饭')
# 3. 定义徒弟类, 继承自师傅类.
class Prentice(School, Master):
# 3.1 定义本类(子类)的 属性.
def __init__(self):
self.kongfu = '[独创蛋炒饭配方]'
# 3.2 定义本类(子类)的 行为, 表示: 炒蛋产饭.
def make_cake(self): # 子类出现和父类重名且一模一样的函数, 称之为: 方法重写.
print(f'使用 {self.kongfu} 制作蛋炒饭')
# 在main函数中测试
if __name__ == '__main__':
# 4. 创建子类的对象
p = Prentice()
# 5. 尝试打印 p对象的 属性 和 行为
print(f'属性: {p.kongfu}')
p.make_cake()
三、多态
多态指的是同一个事物在不同时刻, 不同场景下表现出来的不同形态或状态。现实生活中的多态的表现。比如一杯水, 在高温时是气态, 在常温下是液态,当处于低温的时候是固态。Python中的多态指的是同一个函数 接收不同的参数 会有不同的结果。
多态的条件是有继承、有方法重写、父类引用指向子类对象(传入的是父类或是父类的对象)。
多态的优点是提高了代码的可维护性, 实现了 调用者 和 业务(被调用者)的分离,弊端是无法直接访问子类的特有成员。
代码如下:
# 一个超级超级经典的 多态场景
# 需求如下:
# 构建对象对战平台object_play
# 1 英雄一代战机(战斗力60)与敌军战机(战斗力70)对抗。英雄1代战机失败!
# 2 卧薪尝胆,英雄二代战机(战斗力80)出场!,战胜敌军战机!
# 3 对象对战平台object_play, 代码不发生变化的情况下, 完成多次战斗
# 创建一代英雄战机
class HeroOneJi(object):
def power(self):
return 60
# 创建英雄二代战机 继承一代
class HeroTowJi(HeroOneJi):
def power(self):
return 80
# 创建敌机类
class DiJi(object):
def power(self):
return 70
# 搭建对战平台
def object_play(hj: HeroOneJi, dj: DiJi):
if hj.power() > dj.power():
print('英雄机胜')
elif hj.power() < dj.power():
print('敌机胜')
else:
print('平局')
if __name__ == '__main__':
# 创建一代英雄机对象
hj1 = HeroOneJi()
# 创建一代英雄机对象
hj2 = HeroTowJi()
# 创建敌机对象
dj = DiJi()
# 对战
object_play(hj1,dj)
object_play(hj2,dj)