Python學習面向對象(封裝、繼承、多態)

      網友投稿 818 2022-05-30

      面向對象

      關于面向對象大家應該很熟知,即使說不出他的概念,但是至少記住他的三大特征:封裝、繼承、多態。

      封裝

      所謂封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。

      類的定義

      class ClassName(object): pass

      1

      2

      class定義類的關鍵字.

      ClassName類名,類名的每個單詞的首字母大寫(駝峰規則).

      object是父類名,object是一切類的基類。在python3中如果繼承類是基類可以省略不寫。

      pass 是類身體,由變量(類變量、實例變量)、方法組成(實例方法、靜態方法、類方法)

      class Animal(): eye=2 #類變量 def __init__(self,name): self.animalName=name#實例變量 print("我是初始化方法,也可以叫我構造器") def move(self): print("我是實例方法") @staticmethod def eat(food): Animal.eye print("我是靜態方法:",Animal.eye) @classmethod def run(cls): print("我是類方法:",cls.eye)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      定義一個Animal類:

      類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作為實例變量使用。

      實例變量:定義在方法中的變量,屬于實例。

      初始化方法__init__:被稱為類的構造函數或初始化方法,當創建了這個類的實例時就會調用該方法。

      實例方法:類的實例化對象調用,

      self:代表類的實例,而非類本身,self 在定義實例方法時是必須有的,雖然在調用時不必傳入相應的參數。

      靜態方法:用@staticmethod修飾,類可以不用實例化就可以調用該方法,當然也可以實例化調用,不強制要求傳遞參數。

      類方法:用@classmethod修飾,不需要 self 參數,但第一個參數需要是表示自身類的 cls 參數。

      類的實例化

      沒有new關鍵字,只需要一個實例名來接收類,并且賦上需要初始的值

      dog=Animal("阿黃") cat=Animal("喵喵")

      1

      2

      實例方法的調用:

      當實例調用時,默認將當前實例傳進去。

      類調用時,只能以 類名.method(類實例) 形式調用。

      dog.move() cat.move()

      1

      2

      靜態方法的調用:實例和類調用,沒有默認的參數傳進函數

      Anmial.eat() dog.eat()

      1

      2

      類方法的調用:

      當實例調用classmethod方法時,默認會把當前實例所對應的類傳進去,

      當類調用classmethod方法時,默認把此類傳進去。

      Anmial.run() dog.eat()

      1

      2

      至于__init__(),是在實例化對象時自動調用

      print(dog.eye)#2 print(dog.animalName)#阿黃 print(cat.eye)#2 print(cat.animalName)#喵喵

      1

      2

      3

      4

      class Animal(): eye=2 #類變量 def __init__(self,name): self.animalName=name#實例變量 print("我是初始化方法,也可以叫我構造器") def move(self,way): print("我是實例方法:","%s在%s移動"%(self.animalName,way)) @staticmethod def eat(self,food): Animal.eye print("我是靜態方法:","%s吃%s"%(self.animalName,food)) @classmethod def run(cls,self): print("我是類方法:","%s有%s只眼睛"%(self.animalName,cls.eye)) dog=Animal("阿黃")#我是初始化方法,也可以叫我構造器 cat=Animal("喵喵")#我是初始化方法,也可以叫我構造器 dog.move("馬路上")#我是實例方法: 阿黃在馬路上移動 Animal.eat(dog,"骨頭")#我是靜態方法: 阿黃吃骨頭 Animal.eat(cat,"小魚")#我是靜態方法: 喵喵吃小魚 Animal.run(dog)#我是類方法: 阿黃有2只眼睛 Animal.run(cat)#我是類方法: 喵喵有2只眼睛

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      類的私有屬性和私有方法

      對于python中的類屬性,或者方法,可以通過雙下劃線_或者單下劃線來實現一定程度的私有化。

      _:以單下劃線開頭只能允許其本身與子類進行訪問,(對于實例只是隱藏起來了,可訪問,可修改)。(protected)

      __:以雙下劃線開頭只能允許類本身調用,類的實例不能直接調用。(private)

      python 的私有不是真正的私有,只是約定俗稱的規則。即使私有了我們依然可以通過

      dog._Animal__leg(但是dog._Animal_a 不可以訪問)來訪問私有變量__leg。當然設計者也可以在類中設置方法讓訪問者操作私有屬性。

      示例:

      class Animal(): __leg="四條腿" _eye="兩只眼睛" def __init__(self,name): self.__name=name def get__leg(self): return self.__leg def set__leg(self,leg): self.__leg=leg def __play(self): print("%s在玩"%self.__name) dog=Animal("小狗") print(dog._eye)#兩只眼睛 print(dog.get__leg())#四條腿 print(dog._Animal__leg)#四條腿 #print(dog._Animal_eye)#AttributeError: 'Animal' object has no attribute '_Animal_eye' dog.set__leg("三條腿") print(dog.get__leg())#三條腿 print(dog._Animal__name)#小狗 dog._Animal__play()#小狗在玩 print(dog.__dict__)#{'_Animal__name': '小狗', '_Animal__leg': '三條腿'} print(dir(dog))#dir查看類的所有屬性和方法 ['_Animal__leg', '_Animal__name', '_Animal__play', '__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__', '_eye', 'get__leg', 'set__leg'] 從上述也可以看出__leg ,在內存中是_Animal__leg

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      注:前后都有雙下劃線的是python的特殊方法如__init__(), __del__()等。

      繼承:

      繼承是指這樣一種能力:它可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。

      python的繼承分單繼承和多繼承。

      示例:

      class man(): __sing="唱歌" _dance="跳舞" def __init__(self,name,age): self.name=name self.age=age def say(self): print("我是%s,我%s歲。"%(self.name,self.age)) class son(man): def __init__(self,sex,name,age): self.sex=sex super().__init__(name,age) class girl(man): pass son=son("男","張三",12) son.say()#我是張三,我12歲。 girl=girl("小紅",14) girl.say()#我是小紅,我14歲。 print(sorted(dir(son),reverse=True)) #['sex', 'say', 'name', 'age', '_man__sing', '_dance', '__weakref__', '__subclasshook__', '__str__', '__sizeof__', '__setattr__', '__repr__', '__reduce_ex__', '__reduce__', '__new__', '__ne__', '__module__', '__lt__', '__le__', '__init_subclass__', '__init__', '__hash__', '__gt__', '__getattribute__', '__ge__', '__format__', '__eq__', '__doc__', '__dir__', '__dict__', '__delattr__', '__class__']

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      son,girl都繼承了man的屬性和方法,從dir(son)可看出,__sing沒有繼承,_dance繼承了。

      我舉了一個祖孫三代的例子:

      爺爺有一個名字,會說話,會踢足球;父親繼承了爺爺,但是會跑,并且重寫了play方法會打籃球;小朋友是父親的兒子,繼承了父親,自然也繼承了爺爺,但是他并不會打籃球,他會踢足球。問題來了,爺爺和父親都有play(),小朋友到底繼承了誰的play()?

      首先請看示例:

      class Grandpa(): def __init__(self,name): self.name=name def say(self): print("%s會說話"%self.name) def play(self): print("%s會踢足球"%self.name) class Father(Grandpa): def run(self): print("%s會跑了"%self.name) def play(self): print("%s會打籃球"%self.name) class Child(Father,Grandpa): def play(self): #super(Child, self).play() super(Father, self).play() print(Child.__mro__)#(, , , ) c=Child("小朋友") c.run()#小朋友會跑了 c.say()#小朋友會說話 c.play()#小朋友會踢足球

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      我們可以通過Child.__mro__打印Child的繼承路線:(請記住這個繼承順序,不能亂)

      (, , , )

      1

      首先小朋友是他自己,其次他是Father的孩子,其次是Granpa的孫子,再其次他的祖先是object,這個繼承順序不能亂,就像祖孫三代的關系不能亂。

      默認小盆友是繼承了父親的打籃球,但是我現在希望的是小盆友是繼承爺爺的踢足球,那就要重寫play方法,修改繼承順序:

      super(Father, self).play() #super里寫的Father并不是繼承Father,而是Father的上一輩Grandpa #默認是這個樣子的 super(Child, self).play()

      1

      2

      3

      4

      5

      其實可以直接用類名調用相應的play方法(這樣child就既會踢足球又會打籃球了)如:

      def play(self): Grandpa.play(self) Father.play(self)

      1

      2

      3

      當然繼承里也不能這樣寫Child(Grandpa,Father)

      因為這樣寫的繼承順序是:

      (, , ,)

      1

      系統會報錯:

      TypeError: Cannot create a consistent method resolution

      order (MRO) for bases Grandpa, Father

      假如Father又有了一個實例屬性age(其他都省略,我們只討論init())

      class Grandpa(): def __init__(self,name): self.name=name class Father(Grandpa): def __init__(self,age,name): self.age=age super().__init__(name) class Child(Father,Grandpa): '''def __init__(self,age,name): super().__init__(age) super(Father, self).__init__(name)''' def sing(self): print("我叫%s,我今年%s歲"%(self.name,self.age)) c=Child(12,"xfy") c.sing() f=Father(12,"f") print(f.name)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      Father自己有了__init__(),重寫了Granpa的__init__(),所以要調用Grandpa的__init__(),這樣Child就默認繼承了Father的__init__(),他就有了name和age。

      多態:

      所謂多態就是指一個類實例的相同方法在不同情形有不同表現形式。多態機制使具有不同內部結構的對象可以共享相同的外部接口。這意味著,雖然針對不同對象的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以調用。

      python的多態并沒什么好講的

      當派生類,重寫了基類的方法時就實現了多態性。(子類重寫父類方法)

      python的封裝、繼承、多態就先告一段落,有任何疑問都可以留言評論。

      Python學習之面向對象(封裝、繼承、多態)

      Python 面向對象編程

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:創建型設計模式簡介
      下一篇:ZooKeeper快速入門系列(3) | Zookeeper的內部原理(六大原理)
      相關文章
      亚洲日本VA午夜在线电影| 在线观看亚洲AV每日更新无码| 亚洲精品中文字幕无码A片老| 亚洲精品中文字幕无码AV| 久久久久久久久亚洲| 亚洲av无码片在线播放| 国产亚洲成av片在线观看| 亚洲精品乱码久久久久久蜜桃不卡| 久久久久亚洲爆乳少妇无| 亚洲一区二区精品视频| 国产91精品一区二区麻豆亚洲 | 亚洲视频2020| 亚洲午夜免费视频| 亚洲综合在线成人一区| 亚洲国产日韩女人aaaaaa毛片在线| 99人中文字幕亚洲区| 亚洲国产成人久久三区| 亚洲va成无码人在线观看| 亚洲av永久无码嘿嘿嘿| 国产亚洲精品bv在线观看| 亚洲精品理论电影在线观看| 含羞草国产亚洲精品岁国产精品| 国产精品亚洲综合一区在线观看| 亚洲成A∨人片天堂网无码| 亚洲色偷偷综合亚洲AV伊人| 亚洲最大av无码网址| 亚洲午夜久久久久久噜噜噜| 亚洲va久久久噜噜噜久久| 亚洲国产一区在线| 亚洲国产品综合人成综合网站| 亚洲国产精品免费观看| 亚洲av午夜电影在线观看 | 国产亚洲综合视频| 久久精品国产亚洲7777| 国产亚洲综合成人91精品| 亚洲视频.com| 中文字幕在线日亚洲9| jjzz亚洲亚洲女人| 亚洲日韩中文字幕在线播放| 亚洲另类激情综合偷自拍| 亚洲乱码一二三四区国产|