python 之 面向對象基礎(繼承與派生,經典類與新式類)

7.2 繼承與派生

7.21繼承

1、什麼是繼承? 繼承是一種新建類的的方式,在python中支持一個子類繼承多個父類。新建的類稱為子類或者派生類,父類又可以稱為基類或者超類,子類會”遺傳“父類的屬性。

2、為什麼要用繼承 減少代碼冗餘

class ParentClass1:
    pass
class ParentClass2:
    pass
class Subclass1(ParentClass1):
    pass
class Subclass2(ParentClass1,ParentClass2):
    pass
print(Subclass1.__bases__)  #(<class '__main__.ParentClass1'>,)
print(Subclass2.__bases__)  #(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

3、繼承是類與類之間的關係,尋找這種關係需要先抽象再繼承

class OldboyPeople:
    school = 'oldboy'def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
​
class OldboyTeacher(OldboyPeople):          #繼承OldboyPeople類
    def change_score(self):
        print('teacher %s is changing score' %self.name)
​
class Oldboystudent(OldboyPeople):          #繼承OldboyPeople類
    def choose(self):
        print('student %s choose course' %self.name)
​
tea1 = OldboyTeacher('egon', 18, 'male') # 相當於OldboyTeacher.__init__(...)
stu1=Oldboystudent('alex',73,'female')
​
print(tea1.name,tea1.age,tea1.sex)          #egon 18 male
print(stu1.name,stu1.age,stu1.sex)          #alex 73 female

7.22 派生

派生:子類定義自己新的屬性,如果與父類同名,以子類自己的為準

class OldboyPeople:
    school = 'oldboy'
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
    def f1(self):
        print('爹的f1')
class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,level,salary):
        self.name=name
        self.age=age
        self.sex=sex
        self.level=level
        self.salary=salary
    def change_score(self):
        print('teacher %s is changing score' %self.name)
    def f1(self):
        print('兒子的f1')
tea1 = OldboyTeacher('egon', 18, 'male',9,3.1)             #傳入6個參數,如果傳入父類ze報錯
print(tea1.name,tea1.age,tea1.sex,tea1.level,tea1.salary)   #egon 18 male 9 3.1

7.23 在子類派生出的新方法中重用父類的功能

方式一:指名道姓地調用(與繼承沒有什麼關係

class OldboyPeople:
    school = 'oldboy'
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
        
class OldboyTeacher(OldboyPeople):    #可有可無
    def __init__(self, name, age, sex, level, salary):
        # self.name = name
        # self.age = age
        # self.sex = sex
        OldboyPeople.__init__(self,name, age, sex)#用 OldboyPeople調用__init__的方式重用父類功能
        self.level = level
        self.salary = salary
​
tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)
print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary) #egon 18 male 9 3.1

方式二:super()調用(嚴格依賴於繼承

super ( ) 的返回值是一個特殊的對象,該對象專門用來調用父類中的屬性,super()會嚴格按照mro列表從當前查找到的位置繼續往後查找

了解:在python2中,需要super(自己的類名,self)

class OldboyPeople:
    school = 'oldboy'
    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex
​
class OldboyTeacher(OldboyPeople):      #必須有父類
    def __init__(self, name, age, sex, level, salary):
        super(OldboyTeacher,self).__init__(name,age,sex)# OldboyPeople.__init__(self,name, age,sex) 
        self.level = level
        self.salary = salary
​
tea1 = OldboyTeacher('egon', 18, 'male', 9, 3.1)
print(tea1.name, tea1.age, tea1.sex, tea1.level, tea1.salary)   #egon 18 male 9 3.1

7.3 經典類與新式類

1、新式類: 繼承object的類,以及該類的子類,都是新式類

在python3中,如果一個類沒有指定繼承的父類,默認就繼承object,所以說python3中所有的類都是新式類

2、經典類(只有在python2才區分經典類與新式類):沒有繼承object的類,以及該類的子類,都是經典類

class Foo():               #在python3中
    passclass Bar(Foo):
    passprint(Foo.__bases__)        #(<class 'object'>,)
print(Bar.__bases__)        #(<class '__main__.Foo'>,)

7.34 在多繼承背景下的屬性查找

屬性查找
   obj.x
   1、先從obj.__dict__
   2、對象的類.__dict__
   3、父類.__dict__
  ..........

如果繼承關係為非菱形結構,則會按照先找B這一條分支,然後再找C這一條分支,最後找D這一條分支的順序直到找到我們想要的屬性

如果繼承關係為菱形結構,那麼屬性的查找方式有兩種,分別是:深度優先和廣度優先

print(F.__mro__) # F.mro() #只有新式類才有這個屬性可以查看線性列表,查看屬性查找順序,經典類沒有這個屬性
点赞

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *