面向对象三大特性
- 封装:根据职责将属性和方法封装到一个抽象的类中。
- 继承:实现代码的重用,相同的代码不需要重复编写
- 多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码灵活度
一. 单继承
应用场景:
类:Animal中有方法eat() drink() run() sleep()
类:Dog中有方法eat() drink() run() sleep() bark()
如果没有继承,那么两个类中重复的方法必须在各自的类中写出来,如果使用继承,Animal为父类,Dog为子类,子类就能拥有父类的所以方法和属性。
继承的语法:
class 子类名(父类名):
pass
子类继承自父类,可以直接享受父类中已经封装好的方法,之后子类只需要封装子类特有的属性和方法。
继承的优点就在于实现代码重用,同时方便修改(仅修改父类方法,子类的就能使用修改后的方法)。
(1)继承的传递性
C类从B类继承,B类从A类继承,那么C类同时具有A类和B类的所有属性和方法。
(2)方法的重写
应用场景:
当父类的方法不能满足子类的需求时,可以对方法进行重写(override)
1)覆盖父类方法
子类中定义同名的方法即可,本质来说,调用方法会先在子类中寻找,如果子类没有该方法则到父类中寻找。
2)对父类方法进行扩展
如果子类方法实现中包含了父类方法实现,那么不使用覆盖的方式而是对父类方法进行扩展。
子类中定义同名方法,在需要的位置使用super().父类方法即可
(3)私有属性
子类对象不能直接访问父类的私有属性和私有方法。
子类对象可以通过父类的公有方法间接访问父类的私有属性和私有方法。
二. 多继承
子类可以拥有多个父类,并且具有所有父类的属性和方法
class 子类名(父类1, 父类2,...):
pass
注意事项:
如果不同的父类之间存在同名的方法,应避免使用多继承。
非要使用会按照MRO搜索顺序执行第一个找到的方法。
Python为所有对象提供了object基类,提供一些内置属性和方法,可以使用dir函数查看。
新式类:以object为基类的类
经典类:不以object为基类的类
在python3中如果不指定父类,会默认使用object作为基类,而python2中不会默认使用object作为基类,所以为了保证代码能够同时在python2和python3中运行,在定义类的时候,如果没有指定父类则统一继承自object。
三. 多态
不同的子类对象调用相同的父类方法,产生不同的执行结果。
以继承和重写父类方法为前提。
# coding:utf-8
# 多态演练
class Virus(object):
def __init__(self, name):
self.name = name
def infect(self):
print("%s传染性不强\n" % self.name)
class SARS(Virus):
def infect(self):
print("%s传染性很强\n" % self.name)
class Person(object):
def __init__(self, name):
self.name = name
def infect_by_virus(self, virus):
print("%s被%s感染" % (self.name, virus.name))
virus.infect() # 多态体现在这,不同子类调用相同方法有不同效果
xiaoming = Person("小明")
simple_virus = Virus("普通病毒")
ncp_virus = SARS("新型冠状病毒")
xiaoming.infect_by_virus(simple_virus)
xiaoming.infect_by_virus(ncp_virus)
输出: