Python 入门 14 —— 类的继承

一、基类与派生类

在定义类时,可以在类名后面添加一对小括号“()”,用于指定新定义的类继承自哪些类。例如:

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__']

———————————————— 本篇完 ————————————————

看完之后,麻烦您顺手点击下方 “点赞” 两个字给我点个赞吧 ^-^ , 谢谢您了。

如果您还能像我小学一年级班主任好老师那样,给我随心写上几句表扬或批评的话语,那真是感激不尽!

在我人生的道路上,有了您的鼓励和指导,我一定成长快快。

发布了28 篇原创文章 · 获赞 6 · 访问量 2274

猜你喜欢

转载自blog.csdn.net/Jeff888999/article/details/103984998