python面向對象三大特性之繼承、多態、封裝


一、繼承

  什么是繼承          

    所謂繼承指提供了同一類對象共性的處理方法,子類繼承父類共性的東西。 這樣有利於代碼的復用性,即子類擁有父類的方法。通過繼承創建的新類稱為“子類”或“派生類”,被繼承的類稱為“基類”、“父類”或“超類”。

  繼承可以想象成什么是什么的關系

    python中類的繼承分為:單繼承和多繼承

復制代碼
class Parent1: # 父類1
    pass
class Parent2: #父類2
    pass
class Son1(Parent1):  #單繼承,基類是ParentClass1,派生類是Son1
    pass
class Son2(Parent1,Parent2):  #多繼承,父類是Parent1和Parent2,派生類是Son2
    pass
復制代碼

      查看繼承

復制代碼
>>> Son1.__bases__ #__base__只查看從左到右繼承的第一個父類,__bases__則是查看所有繼承的父類
(<class '__main__.Parent1'>,)
>>> Son2.__bases__
(<class '__main__.Parent1'>, <class '__main__.Parent2'>)
如果沒有指定基類,python的類會默認繼承object類,object是所有python類的基類
>>> Parent1.__bases__
(<class 'object'>,)
復制代碼
復制代碼
 
         
# class Animal:   
# def __init__(self,name,eat,drink,push,shit):
# self.name=name
# self.eat= eat
# self.drink= drink
# self.push= push
# self.shit= shit
# class Dog(Animal):
# def cry(self):
# print('%s汪汪汪'%self.name) #在子類中可以使用父類繼承的name
# class Cat(Animal):
# def cry(self):
# print('%s喵喵喵'%self.name)
#
# teddy=Dog('泰迪','吃','喝','拉','撒')
# cat1=Cat('加菲','吃','喝','拉','撒')
# print(cat1.name) #調用屬性無需添加()
# teddy.cry() #調用方法需要添加(),因為方法本質是函數
加菲

泰迪汪汪汪
復制代碼

      在python3中,子類執行父類的方法也可以直接用super方法.

復制代碼
# class Animal:
#     def __init__(self,name,eat,drink,push,shit):
#         self.name=name
#         self.eat= eat
#         self.drink= drink
#         self.push= push
#         self.shit= shit
#     def run(self):
#         print('%s running'%self.name)
# class Dog(Animal):
#     def cry(self): 
#       super(Dog,self).run() #super(Dog,self).run() =Animal().run(self)=super().run() 執行父類的方法
#         print('%s汪汪汪'%self.name)
# class Cat(Animal):
#     def cry(self):   
      super().__init()  #執行父類的屬性     # print('%s喵喵喵'%self.name) # # teddy=Dog('泰迪','吃','喝','拉','撒') # cat1=Cat('附近反','吃','喝','拉','撒') # print(teddy.name) # teddy.cry()
復制代碼

      多繼承順序

        python3以上(新式類): 廣度優先

        python2(經典類)   :深度優先

復制代碼
class A(object):
    def test(self):
        print('from A')

class B(A):
    def test(self):
        print('from B')

class C(A):
    def test(self):
        print('from C')

class D(B):
    def test(self):
        print('from D')

class E(C):
    def test(self):
        print('from E')

class F(D,E):
    # def test(self):
    #     print('from F')
    pass
f1=F()
f1.test()
print(F.__mro__) #只有新式才有這個屬性可以查看線性列表,經典類沒有這個屬性
<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>
#新式類繼承順序:F->D->B->E->C->A #經典類繼承順序:F->D->B->A->E->C #python3中統一都是新式類 #pyhon2中才分新式類與經典類
復制代碼

 

多態

   什么是多態:相同方法調用,執行不同動作

    向不同的對象發送同一條消息(!!!obj.func():是調用了obj的方法func,又稱為向obj發送了一條消息func),不同的對象在接收時會產生不同的行為(即方法)。 也就是說,每個對象可以用自己的方式去響應共同的消息。所謂消息,就是調用函數,不同的行為就是指不同的實現,即執行不同的函數。

import abc class Animal(metaclass=abc.ABCMeta): #同一類事物:動物
@abc.abstractmethod def talk(self): pass

class People(Animal): #動物的形態之一:人
def talk(self): print('say hello') class Dog(Animal): #動物的形態之二:狗
def talk(self): print('say wangwang') class Pig(Animal): #動物的形態之三:豬
def talk(self): print('say aoao') def func(object)   object.talk() #我們可以定義一個統一的接口來使用 三個類都有talk的方法

封裝

  什么是封裝:

    所謂封裝,也就是把客觀事物封裝成抽象的類,並且類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏。。封裝是面向對象的特征之一,是對象和類概念的主要特性。 簡單的說,一個類就是一個封裝了數據以及操作這些數據的代碼的邏輯實體。在一個對象內部,某些代碼或某些數據可以是私有的,不能被外界訪問。通過這種方式,對象對內部數據提供了不同級別的保護,以防止程序中無關的部分意外的改變或錯誤的使用了對象的私有部分。

在python中用雙下划線開頭的方式將屬性隱藏起來(設置成私有的)

     私有靜態變量設置:設置靜態的私有變量就是 變量名前面添加雙下划線(例如:__Staic),設置私有變量后不要在類的外面調用,因為我們設置私有的就是為了不讓外面的人用到此變量,並且我們也不能在一個類的外部創建一個“私有”的變量,,如果非要在外部調用的話也可以方法詳見下面的例子:

#!/usr/bin/python # -*- encodeing:utf-8 -*-
class A: STATIC = 'aaa'  # 正常的靜態變量
    __S = 'caoyf'   # 私有的變量
    def func(self): print(A.__S)   #在類的里面正常調用類的變量,如果在類的里面調用python會自動給我們進行變形,其實A.__S = A._A__S # print(A.__S) # 使用此種方法調用會報錯,因為私有變量原則上來講不能在外部調用
print(A.__dict__)   #使用這種方法打印時可以看到A.__S已經轉移成'_A__S'了
print(A._A__S)   #如果非要在外部調用可以使用此種方法。
A.__Cao = 'aaaaaaa'  # 外部不能創建一個私有的變量
print(A.__Cao) c = A() c.func()

      私有對象屬性和私有方法:設置這些和設置私有變量時一樣,私有的靜態變量、對象屬性 、方法都是共有一下共同點:

         私有的 只能在類的內部定義和使用
     __名字
     在類外部使用私有靜態變量 _類名__私有的名字
     私有的名字 不能被子類繼承
具體實例如下:
#!/usr/bin/python # -*- encodeing:utf-8 -*-
class B: def __init__(self,name,pwd): self.name = name self.__pwd = pwd   # 創建對象的私有屬性
    def get_pwd(self):     # 創建一個方法
        print(self.__pwd) # 查看pwd這個私有屬性
b = B('caoyf','123.com') b.get_pwd() print(b._B__pwd)  # 當在類外部的時候,我們也不能直接使用對象的私有屬性
class C: def __ppt(self):    #創建一個私有的方法
        print('ppt') def open(self): self.__ppt() print('打開文件') c = C() c._C__ppt() # 不能直接調用
c.open()

    property:

      定義:將一個方法偽裝成一個屬性,這里有提供了兩種對私有的修改和刪除方法,修改:方法名.setter  刪除:方法名.deleter,具體的實例如下:

 

#!/usr/bin/python # -*- encodeing:utf-8 -*-
class Person: def __init__(self,name,height,witeght): self.name = name self.__height = height self.__witeght = witeght @property # 使用此方法偽裝成屬性
    def jisuan(self): print(self.__witeght / (self.__height * 2)) cao = Person('caoyf',1.67,82) # cao.jisuan() # 正常調用方法是實例化的名字.方法()
cao.jisuan  #偽裝成屬性后調用方法不需要添加括號

class Foo: def __init__(self,name): self.__name = name  # 設置私有屬性
    @property  # 使用此方法偽裝成屬性
    def name(self): print(self.__name) @name.setter #使用setter方法 修改私有屬性的名字,但是方法名一定要與源來的方法名字一直
    def name(self,new_name): self.__name = new_name @name.deleter #使用deleter方法 刪除私有屬性的名字,但是方法名一定要與源來的方法名字一直
    def name(self): raise  TypeError('Can not delete') a = Foo('caoyf') # a.name # a.name = 'caosy'
del a.name a.name

未完待續。。。。。。。。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM