1. 程式人生 > 實用技巧 >面向物件之繼承等相關內容-26

面向物件之繼承等相關內容-26

day26

1.繼承介紹

"""
1 什麼是繼承
繼承是一種新建類的方式,新建的類稱之為子類,被繼承的類稱之為
父類、基類、超類

python支援多繼承

2 為何要繼承
子類會遺傳父類的屬性,所以繼承是用來解決類與類之間程式碼冗餘問題

3、如何實現繼承

"""
# class Parent1:
# pass
#
# class Parent2:
# pass
#
# class Sub1(Parent1):
# pass
#
# class Sub2(Parent1,Parent2):
# pass
#
# print(Sub1.__bases__)
# print(Sub2.__bases__)
#


# 繼承案列:
class OldboyPeople:
school = "oldboy"


class Student(OldboyPeople):
def __init__(self,name,age,gender,stud_id,course):
self.name = name
self.age = age
self.gender = gender
self.stu_id = stud_id
self.course = course

def choose(self):
print('%s 正在選課' %self.name)

class Teacher(OldboyPeople):
def __init__(self,name,age,gender,salary,level):
self.name = name
self.age = age
self.gender = gender
self.salary = salary
self.level = level

def score(self,stu,num):
stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
tea1=Teacher("egon",18,'male',2000,10)


print(stu1.school)

2.在子類派生的新方法中重用父類的功能方式一

# 在子類派生的新方法中重用父類的功能
# 方式一:指名道姓地呼叫某一個類的函式
# 特點:不依賴於繼承關係
#
class OldboyPeople:
school = "oldboy"
# 空物件,"艾利克斯",73,'male'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender

def f1(self):
print('1111111')

class Student(OldboyPeople):
# 空物件,"艾利克斯",73,'male',1001,"python全棧開放"
def __init__(self,name,age,gender,stu_id,course):
OldboyPeople.__init__(self,name,age,gender) # OldboyPeople.__init__(空物件,"艾利克斯",73,'male')
self.stu_id = stu_id
self.course = course


def choose(self):
print('%s 正在選課' %self.name)

def f1(self):
OldboyPeople.f1(self)
print("22222")

class Teacher(OldboyPeople):
def score(self,stu,num):
stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
# tea1=Teacher("egon",18,'male',2000,10)


stu1.f1()

3.屬性查詢

# 例1:
# class Foo:
# def f2(self):
# print("Foo.f2")
#
# def f1(self):
# print('Foo.f1')
# self.f2() # obj.f2()
#
#
# class Bar(Foo):
# def f2(self):
# print("Bar.f2")




# obj = Bar()
#
# obj.f1()
"""
Foo.f1
Bar.f2
"""


# 例2:父類如果不想讓子類覆蓋自己的方法,可以在方法名前加字首__
class Foo:
def __f2(self): # _Foo__f2
print("Foo.f2")

def f1(self):
print('Foo.f1')
self.__f2() # obj._Foo__f2()


class Bar(Foo):
def __f2(self): # _Bar__f2
print("Bar.f2")




obj = Bar()

obj.f1()

4.繼承的實現原理

# coding:utf-8
# 1 補充知識:
# 新式類:但凡是繼承了object類的子類,以該子類子子孫孫類都稱之為新式類
# 經典類:沒有繼承了object類的子類,以該子類子子孫孫類都稱之為經典類

# python3中全都是新式類,python2中才有經典類:
# 在python3中沒有繼承任何類的類會預設繼承object類
# class Foo(object):
# pass
#
# print(Foo.__bases__)

# 2 繼承的實現原理
# 2.1 菱形問題:一個子類繼承的多條件分支最終匯聚到一個非object類,在菱形繼承下
# 新式類與經典類關於屬性查詢的方式不同

# 新式類:廣度優先
# 經典類:深度優先


# 例1:非菱形繼承,經典類與新式類的屬性查詢順序都一樣
# class E:
# # def test(self):
# # print('from E')
# pass
#
# class F:
# def test(self):
# print('from F')
#
#
# class B(E):
# # def test(self):
# # print('from B')
# pass
#
# class C(F):
# def test(self):
# print('from C')
#
#
# class D:
# def test(self):
# print('from D')
#
#
# class A(B, C, D):
# # def test(self):
# # print('from A')
# pass
#
# obj=A()
# obj.test()

# 例2:菱形繼承
class G(object): # 在python2中,未繼承object的類及其子類,都是經典類
# def test(self):
# print('from G')
pass

class E(G):
# def test(self):
# print('from E')
pass

class F(G):
# def test(self):
# print('from F')
pass

class B(E):
# def test(self):
# print('from B')
pass

class C(F):
# def test(self):
# print('from C')
pass

class D(G):
# def test(self):
# print('from D')
pass

class A(B,C,D):
# def test(self):
# print('from A')
pass

# obj=A()
# obj.test()

print(A.mro())

附加 類的繼承的底層 C3演算法

day26

1.繼承介紹

"""
1 什麼是繼承
繼承是一種新建類的方式,新建的類稱之為子類,被繼承的類稱之為
父類、基類、超類

python支援多繼承

2 為何要繼承
子類會遺傳父類的屬性,所以繼承是用來解決類與類之間程式碼冗餘問題

3、如何實現繼承

"""
# class Parent1:
# pass
#
# class Parent2:
# pass
#
# class Sub1(Parent1):
# pass
#
# class Sub2(Parent1,Parent2):
# pass
#
# print(Sub1.__bases__)
# print(Sub2.__bases__)
#


# 繼承案列:
class OldboyPeople:
school = "oldboy"


class Student(OldboyPeople):
def __init__(self,name,age,gender,stud_id,course):
self.name = name
self.age = age
self.gender = gender
self.stu_id = stud_id
self.course = course

def choose(self):
print('%s 正在選課' %self.name)

class Teacher(OldboyPeople):
def __init__(self,name,age,gender,salary,level):
self.name = name
self.age = age
self.gender = gender
self.salary = salary
self.level = level

def score(self,stu,num):
stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
tea1=Teacher("egon",18,'male',2000,10)


print(stu1.school)

2.在子類派生的新方法中重用父類的功能方式一

# 在子類派生的新方法中重用父類的功能
# 方式一:指名道姓地呼叫某一個類的函式
# 特點:不依賴於繼承關係
#
class OldboyPeople:
school = "oldboy"
# 空物件,"艾利克斯",73,'male'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender

def f1(self):
print('1111111')

class Student(OldboyPeople):
# 空物件,"艾利克斯",73,'male',1001,"python全棧開放"
def __init__(self,name,age,gender,stu_id,course):
OldboyPeople.__init__(self,name,age,gender) # OldboyPeople.__init__(空物件,"艾利克斯",73,'male')
self.stu_id = stu_id
self.course = course


def choose(self):
print('%s 正在選課' %self.name)

def f1(self):
OldboyPeople.f1(self)
print("22222")

class Teacher(OldboyPeople):
def score(self,stu,num):
stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
# tea1=Teacher("egon",18,'male',2000,10)


stu1.f1()

3.屬性查詢

# 例1:
# class Foo:
# def f2(self):
# print("Foo.f2")
#
# def f1(self):
# print('Foo.f1')
# self.f2() # obj.f2()
#
#
# class Bar(Foo):
# def f2(self):
# print("Bar.f2")




# obj = Bar()
#
# obj.f1()
"""
Foo.f1
Bar.f2
"""


# 例2:父類如果不想讓子類覆蓋自己的方法,可以在方法名前加字首__
class Foo:
def __f2(self): # _Foo__f2
print("Foo.f2")

def f1(self):
print('Foo.f1')
self.__f2() # obj._Foo__f2()


class Bar(Foo):
def __f2(self): # _Bar__f2
print("Bar.f2")




obj = Bar()

obj.f1()

4.繼承的實現原理

# coding:utf-8
# 1 補充知識:
# 新式類:但凡是繼承了object類的子類,以該子類子子孫孫類都稱之為新式類
# 經典類:沒有繼承了object類的子類,以該子類子子孫孫類都稱之為經典類

# python3中全都是新式類,python2中才有經典類:
# 在python3中沒有繼承任何類的類會預設繼承object類
# class Foo(object):
# pass
#
# print(Foo.__bases__)

# 2 繼承的實現原理
# 2.1 菱形問題:一個子類繼承的多條件分支最終匯聚到一個非object類,在菱形繼承下
# 新式類與經典類關於屬性查詢的方式不同

# 新式類:廣度優先
# 經典類:深度優先


# 例1:非菱形繼承,經典類與新式類的屬性查詢順序都一樣
# class E:
# # def test(self):
# # print('from E')
# pass
#
# class F:
# def test(self):
# print('from F')
#
#
# class B(E):
# # def test(self):
# # print('from B')
# pass
#
# class C(F):
# def test(self):
# print('from C')
#
#
# class D:
# def test(self):
# print('from D')
#
#
# class A(B, C, D):
# # def test(self):
# # print('from A')
# pass
#
# obj=A()
# obj.test()

# 例2:菱形繼承
class G(object): # 在python2中,未繼承object的類及其子類,都是經典類
# def test(self):
# print('from G')
pass

class E(G):
# def test(self):
# print('from E')
pass

class F(G):
# def test(self):
# print('from F')
pass

class B(E):
# def test(self):
# print('from B')
pass

class C(F):
# def test(self):
# print('from C')
pass

class D(G):
# def test(self):
# print('from D')
pass

class A(B,C,D):
# def test(self):
# print('from A')
pass

# obj=A()
# obj.test()

print(A.mro())

附加 類的繼承的底層 C3演算法

按照上圖所示,C3演算法的原理大致是如下會產生4個列表
[A,B,D,E][A,C,D,E][A,D,E][A,B,C,D]
這4個列表分別的意義是 都是從A一路到頭的順序 先按照深度優先畫出路線
1. 按照A同時繼承的順序,第一個是 A B D E
2. 按照A同時繼承的順序,第二個是 A C D E
3. 按照A同時繼承的順序,第三個是 A D E
4. 按照A同時繼承的順序,第四個是A的父類排隊 A B C D

工作開始
第一步 拿出第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
A
將得到 現在的四個列表 [B,D,E][C,D,E][D,E][B,C,D]
第二步 拿出現有第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
A B
將得到 現在的四個列表 [D,E][C,D,E][D,E][C,D]
第三步 拿出現有第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
當拿出D時候 D是其中一個列表的尾部 那麼 跳過第一個列表 從第二個列表中的第一個位置元素開始
就得到C
A B C
將得到 現在的四個列表 [D,E][D,E][D,E][D]
第四步 只剩下 D E兩個類了 已經表明 D 繼承 E
所以順序是 A B C D E

按照上圖所示,C3演算法的原理大致是如下會產生4個列表
[A,B,D,E][A,C,D,E][A,D,E][A,B,C,D]
這4個列表分別的意義是 都是從A一路到頭的順序 先按照深度優先畫出路線
1. 按照A同時繼承的順序,第一個是 A B D E
2. 按照A同時繼承的順序,第二個是 A C D E
3. 按照A同時繼承的順序,第三個是 A D E
4. 按照A同時繼承的順序,第四個是A的父類排隊 A B C D

工作開始
第一步 拿出第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
A
將得到 現在的四個列表 [B,D,E][C,D,E][D,E][B,C,D]
第二步 拿出現有第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
A B
將得到 現在的四個列表 [D,E][C,D,E][D,E][C,D]
第三步 拿出現有第一個列表的第一個位置元素 作為第一順序,確認是否是其餘三個列表中的尾部,如果是,放棄查詢下一個列表,如果不是,則將作為第一個查詢順序,並在所有列表中去除
當拿出D時候 D是其中一個列表的尾部 那麼 跳過第一個列表 從第二個列表中的第一個位置元素開始
就得到C
A B C
將得到 現在的四個列表 [D,E][D,E][D,E][D]
第四步 只剩下 D E兩個類了 已經表明 D 繼承 E
所以順序是 A B C D E