一、基类与派生类
在定义类时,可以在类名后面添加一对小括号“()”,用于指定新定义的类继承自哪些类。例如:
class 类名(基类1,基类2,基类3...): pass
被继承的类和新定义的类通常分别被称为“基类”和“派生类”。当然,基类和派生类的称呼是相对的:基类可能也是从其它的类继承而来,是其它类的派生类;同样,派生类也可以被其它的类继承,而成为基类。
基类和派生类很多时候又分别被称作“父类”和“子类”。
定义类时,可以从单个基类继承(单继承),也可以从多个基类继承(多继承)。多继承时,各基类之间用逗号“,”分隔。
二、派生类的成员
1、通过“复制”,派生类得到所有基类的公有成员和保护成员。
在生成派生类时,所有基类的公有成员和保护成员都会“复制”一份给派生类,所以,派生类拥有所有基数的公有成员和保护成员,通过派生类的类名和派生类对象的对象名,可以访问所有基数的公有成员和保护成员。
因为基类的私有成员在生成派生类时没有被“复制”,所以,通过派生类的类名和派生类对象的对象名不能访问基数的私有成员。例如:
class base01:
x1 = 1; _y1 = 2; __z1 = 3
def __init__(self): self.a1 = 11; self._b1 = 12; self.__c1 = 13
class base02:
x2 = 5
class sub01(base01, base02):
v = 100
# 用类名访问
print(sub01.x1, sub01._y1, sub01.x2, sub01.v) # 基类公有成员和保护成员可以访问:1 2 5 100
print(sub01.__z1) # 基类私有成员不能访问:AttributeError: type object 'sub01' has no attribute '__z1'
# 用对象名访问
obj01 = sub01()
print(obj01.x1, obj01._y1, obj01.x2, obj01.v ) # 基类公有成员和保护成员可以访问:1 2 5 100
print(obj01.a1,obj01._b1) # 11 12
print(obj01.__z1) # 基类私有成员不能访问:AttributeError: 'sub01' object has no attribute '__z1'
print(obj01.__c1) # AttributeError: 'sub01' object has no attribute '__c1'
2、多继承时,仅第一个基类的构造函数,会被系统在派生类创建对象之后的第一时间调用,其它基类的创造函数在派生类创建对象时不起作用。例如:
class base03:
def __init__(self): print("base03"); self.a3 = 31;
class base04:
def __init__(self): print("base04"); self.a4 = 41;
class base05:
def __init__(self): print("base05"); self.a4 = 51;
class sub02(base03, base04, base05): pass # base03 为第一基类
obj02 = sub02() # 仅第一基类的构造函数会被调用:base03
print(obj02.a3) # 第一基类的构造函数中设置的对象成员可以访问:31
print(obj02.a4) # 第二基类的构造函数中设置的对象成员不能访问:AttributeError: 'sub02' object has no attribute 'a4'
print(obj02.a5) # 第三基类的构造函数中设置的对象成员不能访问:AttributeError: 'sub02' object has no attribute 'a5'
class sub03(base04, base03, base05): pass # base04 为第一基类
obj03 = sub03() # base04
class sub04(base05, base04, base03): pass # base05 为第一基类
obj04 = sub04() # base05
3、当多个基类间有成员同名时,第一基类的成员会屏蔽其它基类的同名成员。例如:
# base06、 base07、 base08 都有同名成员 a、b、fun()
class base06:
x6 = 61; a = 62; b = 63
def fun(self): print("base06");
class base07:
x7 = 71; a = 72; b = 73
def fun(self): print("base07");
class base08:
x8 = 81; a = 82; b = 83
def fun(self): print("base08");
class sub05(base06, base07, base08): pass # 第一基类:base06
obj05 = sub05()
class sub06(base07, base06, base08): pass # 第一基类:base07
obj06 = sub06()
class sub07(base08, base07, base06): pass # 第一基类:base08
obj07 = sub07()
print(obj05.x6, obj05.a, obj05.b) # 61 62 63
print(obj06.x7, obj06.a, obj06.b) # 71 72 73
print(obj07.x8, obj07.a, obj07.b) # 81 82 83
obj05.fun() # base06
obj06.fun() # base07
obj07.fun() # base08
三、object 类是所有类的鼻祖
在 python 中没有继承任何基类的派生类,都是缺省继承 object 类。也就是说,object 类是所有类的鼻祖。
一个没有继承任何基类,没有定义任何成员与方法的派生类,缺省继承有 object 类的所有成员和方法。例如:
python
class myCls:pass
print(dir(myCls))
# 显示:['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
———————————————— 本篇完 ————————————————
看完之后,麻烦您顺手点击下方 “点赞” 两个字给我点个赞吧 ^-^ , 谢谢您了。
如果您还能像我小学一年级班主任好老师那样,给我随心写上几句表扬或批评的话语,那真是感激不尽!
在我人生的道路上,有了您的鼓励和指导,我一定成长快快。