1、单继承(代码的重用)
语法:class DerivedClassName(BaseClassName),其中DerivedClassName是派生类,BaseClassName是基类、父类或超类。
何时使用继承:当你需要定义几个类,而类与类之间有一些公共的属性和方法,这时就可以把相同的属性和方法作为基类的成员,而特殊的方法及属性则在本类中定义,这样只需要继承基类这个动作,就可以访问到基类的属性和方法了,它提高了代码的可扩展性。
例子1:若子类中定义了与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性。
class Parent:
def hello(self):
print('正在调用父类的方法')
class Child(Parent):#继承Parent类
def hello(self): #重写hello方法
print('正在调用子类的方法')
def study(self): #可以对子类增加一些方法
print('学习中')
>>>p=Parent()
>>> p.hello()
正在调用父类的方法
>>> c=Child()
>>> c.hello()
正在调用子类的方法
例子2:当子类与父类中都有__init__
方法时,即子类重写了父类的构造方法,此时若不显式调用父类的构造函数,父类的构造函数就不会被执行,导致子类实例访问父类初始化方法中初始的变量就会出现问题。
class Person:
def __init__(self):
self.name ="王小明"
def func1(self):
print("function1 is print name:%s"%self.name)
class Boy(Person):
def __init__(self):
self.gender ="male"
def func2(self):
print("function2 is print gender:%s"%self.gender)
>>>b=Boy()
>>>b.gender
'male'
>>>b.func2()
function2 is print gender:male
>>>b.func1() #会报错
Traceback (most recent call last):
File "<pyshell#70>", line 1, in <module>
b.func1()
File "<pyshell#50>", line 5, in func1
print("function1 is print name:%s"%self.name)
AttributeError: 'Boy' object has no attribute 'name'
#错误原因:在子类中,构造函数被重写,但新的构造方法没有任何关于初始化父类的name属性的代码!
为了达到预期的效果,子类的构造方法必须调用其父类的构造方法来进行基本的初始化,有两种解决方法:
方法一:调用未绑定的父类方法
#修改代码
class Boy(Person):
def __init__(self):
#这一行解决问题,直接使用父类名称调用其构造函数
Person.__init__(self)
self.gender ="male"
def func2(self):
print("function2 is print gender:%s"%self.gender)
>>> b=Boy()
>>> b.func1()
function1 is print name:王小明
>>> b.func2()
function2 is print gender:male
'''
在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(称为绑定方法)。但如果直接调用类方法(比如A.__init),那么就没有实例会被绑定。这样就可以自由的提供需要的self参数,这种方法称为未绑定unbound方法。(什么是实例对象、类对象,在后面有讲述)
'''
方法二:使用super函数
```python
#修改代码
class Boy(Person):
def __init__(self):
#这一行解决问题
super().__init__()
self.gender ="male"
def func2(self):
print("function2 is print gender:%s"%self.gender)
>>> b=Boy()
>>> b.func1()
function1 is print name:王小明
'''
super函数会返回一个super对象,这个对象负责进行方法解析,解析过程其会自动查找所有的父类以及父类的父类(即无需给定任何基类的名字),注:self参数已在super()自动传入,在__init__()中将隐式传递,不需要写出(也不能写)。
'''
方法一更直观,方法二可以一次初始化所有超类!
super函数比在超类中直接调用未绑定方法更直观,但是其最大的优点是如果子类继承了多个父类,它只需要使用一次super函数就可以。然而如果没有这个需求,直接使用A.init(self)更直观一些。
super解决钻石继承问题:https://www.tuicool.com/articles/eEzmmay
2、多重继承(一个子类就可以同时获得多个父类的所有功能)
语法:class DerivedClassName(Base1,Base2,Base2)
class Base1:
def func1(self):
print('我是func1')
class Base2:
def func2(self):
print('我是func2')
class Base3(Base1,Base2):
pass
>>>c=Base3()
>>>c.func1()
我是func1
>>>c.func2()
我是func2