1. 程式人生 > 實用技巧 >python 繼承和派生

python 繼承和派生

python內建的類檢視: >>> help(__builtins__)

1、繼承 inheritance / 派生 derived

  【1】 繼承是指從已有的類中派生出新的類,新類具有原類的行為,並能擴充套件新的行為

  【2】 派生類就是從一個已有類中衍生成新類,在新類上可以新增新的屬性和行為

2、作用

  【1】用繼承派生機制,可以將一些共有功能加在基類中,實現程式碼的共享

  【2】在不改變基類的程式碼的基礎上改變原有的功能

3、

  【1】基類(base class) /超類(super class)/ 父類(father class)

  【2】派生類(derived class) / 子類(child class)

4、單繼承

  【1】單繼承是指由一個基類衍生出新的類

  【2】python3 任何類都直接或間接的繼承自object類 object 類是一切類的超類

  class 類名(基類名):

    pass 

# 此示例示意單繼承的用法:
class Human:  # 人類的共性
    def say(self, what):
        print("say:", what)

    def walk(self, distance):  # 走路
        print("走了", distance, '公里')

class Student(Human):
    def
study(self, subject): print("正在學習:", subject) class Teacher(Student): '''說話,行走,教學''' def teach(self, subject): print("正在教:", subject) h1 = Human() h1.say('天氣晴了') h1.walk(5) print('---------------') s1 = Student() s1.walk(4) s1.say('感覺有點累') s1.study('Python') print('===============
') t1 = Teacher() t1.walk(6) t1.say('吃點啥好呢') t1.teach('面向物件') t1.study('轉魔方') class Skill: def fire(self): print("release Fire skill") class Riven: camp='Noxus' def __init__(self,nickname): self.nickname=nickname self.skill5=Skill().fire()#Skill類產生一個物件,並呼叫fire()方法,賦值給例項的skill5屬性 r1=Riven("瑞雯")

5、覆蓋 override

  覆蓋是指在有繼承關係的類中,子類中實現了與基類同名的方法,在子類的例項呼叫該方法時,

  實際呼叫的是子類中的覆蓋版本,這種現象叫做覆蓋。 

In [161]: # 此示例示意B類的works方法覆蓋A類的works方法
     ...: class A:
     ...:     def works(self):
     ...:         print("A.works被呼叫")
     ...:
     ...:
     ...: class B(A):
     ...:     ''' B類繼承自A類'''
     ...:     def works(self):
     ...:         print("B.works被呼叫")
     ...:
     ...:
     ...: b = B()
     ...: b.works()  # 呼叫B類的works
     ...:
     ...: a = A()
     ...: a.works()  # 呼叫A類的works
B.works被呼叫
A.works被呼叫
In [162]: # 此示例示意B類的works方法覆蓋A類的works方法
     ...: class A:
     ...:     def works(self):
     ...:         print("A.works被呼叫")
     ...:
     ...:
     ...: class B(A):
     ...:     ''' B類繼承自A類'''
     ...:     def works(self):
     ...:         print("B.works被呼叫")
     ...:
     ...:
     ...: b = B()
     ...: b.works()  # B.works被呼叫
     ...: A.works(b)  # 用類名顯式呼叫A類的works, A.works被呼叫
     ...:
B.works被呼叫
A.works被呼叫

6、子類呼叫父類中的重名方法

  【1】子類物件顯式呼叫基類(被覆蓋)方法的方式:

    基類名.方法名(例項, 實際呼叫傳參)

  【2】super().方法名(引數) #只能在方法內使用

  【3】super(子類名,子類例項).方法名(引數)

7、super函式

   用於在子類中呼叫父類中被覆蓋的方法

   super(cls, obj)

      cls,子類名。obj,子類的例項

      返回繫結超類的例項

   super()

      返回繫結超類的例項,等同於: super(__class__, 例項方法的第一個引數), 必須在方法內呼叫

     【作用】: 藉助super() 返回的基類的例項間接呼叫其父類的覆蓋方法

In [165]: # 此示例示意用super函式返回的物件呼叫父類的覆蓋方法
     ...: class A:
     ...:     def works(self):
     ...:         print("A.works被呼叫")
     ...:
     ...: class B(A):
     ...:     ''' B類繼承自A類'''
     ...:     def works(self):
     ...:         print("B.works被呼叫")
     ...:
     ...:     def super_work(self):
     ...:         self.works()  # B.works被呼叫
     ...:         super(B, self).works()  # A.works被呼叫
     ...:         super().works()  # A.works被呼叫
     ...:
     ...:
     ...: b = B()
     ...: b.works()  # B.works被呼叫
     ...: super(B, b).works()  # A.works被呼叫
     ...: b.super_work()  # ...
     ...: # super().works() # 出錯,只能在方法內呼叫
     ...: A.works(b)
     ...:
B.works被呼叫
A.works被呼叫
B.works被呼叫
A.works被呼叫
A.works被呼叫
A.works被呼叫

8、繼承中的初始化方法

  當子類中實現了 __init__ 方法,

  基類的初始化方法並不會被呼叫 def __init__(self, ...)

In [166]: # 此示例示意 用super函式顯示呼叫基類__init__初始化方法
     ...: class Human:
     ...:     def __init__(self, n, a):
     ...:         self.name, self.age = n, a
     ...:         print("Human的__init__方法被呼叫")
     ...:
     ...:     def infos(self):
     ...:         print("姓名:", self.name)
     ...:         print("年齡:", self.age)
     ...:
     ...:
     ...: class Student(Human):
     ...:     def __init__(self, n, a, s=0):
     ...:         super().__init__(n, a)  # 顯式呼叫父類的初始化方法
     ...:         self.score = s  # 新增成績屬性
     ...:         print("Student類的__init__方法被呼叫")
     ...:
     ...:     def infos(self):
     ...:         super().infos()  # 呼叫父類的方法
     ...:         print("成績:", self.score)
     ...:
     ...:
     ...: s1 = Student('小張', 20, 100)
     ...: s1.infos()
Human的__init__方法被呼叫
Student類的__init__方法被呼叫
姓名: 小張
年齡: 20
成績: 100