面向對象的三大特性之繼承

單繼承:一個類只繼承一個父類

# 抽離:先有多個有共同點的類,抽離出共性造成的類 => 父類
# 派生:經過已有的父類,再去定義該類的子類,這種方式就叫作派生

# 繼承:繼承是一種關係,子類能夠經過父類獲取屬性和方法,能獲取的根據就是繼承

# 繼承的語法:
# class 父類名:pass
# class 子類名(父類名): pass
class Sup:
pass
class Sub(Sup):
   pass

   # 繼承的規則
# 1.父類的全部未封裝的屬性和方法,子類都能訪問
# 2.父類的全部封裝的屬性和方法,子類都不能訪問
#       -- 在外界經過子類或子類對象,不能訪問
#       -- 在子類內部經過子類或子類對象也不能訪問

class Sup:
__num = 10  # 封裝被改名爲_Sup__num
class Sub(Sup):
   def test(self):
  print(self.__num)  # 本質去訪問_Sub__num,因此不能訪問
      
    # 繼承父類的方法:子類沒有明文書寫父類的方法,經過繼承關係拿到
    class Sup:
def test(self):
  print(self)  # 父類對象調用就是父類對象,子類對象調用就是當前調用的子類對象
      
    class Sub(Sup):
    pass
Sub().test()
   
# 重寫父類的方法:子類明文書寫父類同名的方法,而且實現體自定義
class Sup:
def test(self):
  print(self)  # 父類對象調用就是父類對象,子類對象調用就是當前調用的子類對象
      
    class Sub(Sup):
    def test(self):
  print('本身的方法', self)
   Sub().test()
    
# 重用父類的方法:子類明文書寫父類同名的方法,有本身的實現體,但也用父類原有的功能
class Sup:
def test(self):
  print(self)  # 父類對象調用就是父類對象,子類對象調用就是當前調用的子類對象
      
    class Sub(Sup):
    def test(self):
  super().test()  # 本質 super(Sub, self).test() py2必須這麼寫
      print('本身的方法', self)
    Sub().test()

瞭解:重用概念

# java中存在方法的重用
def fn():
pass
def fn(num):
   pass
# fn()調用不傳參調用第一個fn
   # fn(10)調用傳入一個參數調用第二個fn

super關鍵字

class Sup:
def __init__(self, name):
  self.name = name
   
    def test(self):
      print(self)
   
    
class Sub(Sup):
# 默認父級的__init__能夠被繼承過來,
# 可是會出現子類對象的屬性比父類多
   def __init__(self, name, salary):
      super().__init__(name)  # 父級有的共性功能經過super()交給父級作
      self.salary = salary  # 子類特有的本身來完成
    
    # 有繼承關係下,只要名字相同,即便參數不一樣,仍是屬於同一個方法
   def test(self, num):
      super().test()  # 使用父級的方法
      print(num)
       
    # 外界經過Sub對象來調用test方法,必定找本身的test方法(屬性的查找順序)
    

   # 重點:super() 能夠獲得調用父級功能的對象,調用者仍是子類對象
#      -- super()只能在子類的方法中使用
#      -- super()本質 super(子類類名, 當前對象)
#      -- super().父類普通方法 | super().__init__() | super()能調用父類全部可繼承方法

多繼承

# 屬性的查找順序:優先找本身的,若是沒有,按照繼承前後查找父級
class A:
name = 'A'
num = 10
   
   class B:
name = 'B'
count = 100
   
   # 子類能夠繼承全部父類的全部可繼承屬性
class C(A, B):  # 本身 => A => B
# name = 'C'
pass

複雜多繼承

class A:
name = "A"
class B(A):
   name = "B"
class C:
   name = "C"
class D(C):
   name = "D"
class E(B, D):  # 先將B的全部父級們找完再找D的分支
   name = "E"
print(E.mro())  # E => B => A => D => C

菱形繼承

# 經典類:python2中才有,沒有繼承任何類的類 - 深度優先
# 新式類:python2中直接或間接繼承object的類,python中所定義的全部類 - 廣度優先

# 深度優先,在查找第一個分支是就將菱形的頭查找了
# 廣度優先,菱形的頭在全部分支查找接收後再被查找

# 經過 類.mro() 查看繼承順序圖

總結

'''
繼承

1.父類:在類後()中寫父類們
class A:pass
class B:pass
class C(A, B):pass

2.屬性查找順序:本身 -> ()左側的父類 -> 依次往右類推

3.抽離:先定義子類,由子類的共性抽離出父類 - 派生:父類已經建立,經過父類再去派生子類

4.繼承關係
  -- 1)父類的全部非封裝的屬性和方法均能被繼承
  -- 2)父類的全部封裝的屬性和方法均能被繼承
  -- 3)在子類中要去使用父類的方法
      -- 子類繼承父類方法:子類不須要去實現父類的方法,子類對象能夠直接調用父類方法
      -- 重寫父類的方法:方法名與父類相同,實現體與父類不一樣,子類對象調用的是自身方法
      -- 重用父類的方法:方法名與父類相同,實現體中有本身的邏輯也調用了父類的方法(super())
          -- super():在子類中獲取能夠調用父類方法的對象,且在父類中體現的調用者子類或子類對象
      
5.複雜繼承:一個類能夠繼承多個類,查找順序是根據繼承父類從左往右的順序,而且在查找第一個父類時,將父類的父類也進行查找(一個父類分支所有查找完畢纔去查找下一個父類分支)  

6.棱形繼承
  -- 經典類:py2中類不默認繼承object,因此沒有明確繼承的類就沒有繼承任何類,這樣的類稱之爲經典類
  -- 新式類:全部直接或間接繼承object的類,py2中主動繼承object的類及py3中全部的類
  
  -- 前提:父類中有共有屬性或方法,子類沒有本身去定義這些屬性和方法,必須從父類中獲取,到底從哪一個父類中獲取
  -- 經典類:深度查找 a -> b -> d -> c
  -- 新式類:廣度優先 a -> b -> c -> d
  d
b      c
  a
'''
相關文章
相關標籤/搜索