面向對象的三大特性:python
封裝程序員
就是將內容封裝到某個地方,之後再去調用被封裝在某處的內容。 將內容封裝到某處 從某處調用被封裝的內容數據庫
就是將內容封裝到某個地方,之後再去調用被封裝在某處的內容。 第二步:從某處調用被封裝的內容:有兩種狀況: (1)經過對象直接調用編程
class Foo: def __init__(self, name, age): self.name = name self.age = age def detail(self): print (obj1.name) # 直接調用對象的name屬性 print (obj1.age) # 直接調用對象的age屬性 obj1 = Foo('wupeiqi', 18) Obj1. detail() # Python默認會將obj1傳給self參數,即:obj1.detail(obj1),因此,此時方法內部的 self = obj1, 即:self.name 是 wupeiqi ;self.age 是 18 obj2 = Foo('alex', 73) Obj2. detail()
(2)、經過self間接調用被封裝的內容函數式編程
class Foo: def __init__(self, name, age): self.name = name self.age = age def detail(self): print (obj1.name) # 直接調用對象的name屬性 print (obj1.age) # 直接調用對象的age屬性 obj1 = Foo('wupeiqi', 18) Obj1. detail() # Python默認會將obj1傳給self參數,即:obj1.detail(obj1),因此,此時方法內部的 self = obj1, 即:self.name 是 wupeiqi ;self.age 是 18 obj2 = Foo('alex', 73) Obj2. detail()
繼承函數
將多個類共有方法提取到父類,子類僅需繼承父類而沒必要一一實現每一個方法 注:除了子類和父類的稱謂,你可能看到過 派生類 和 基類 ,他們與子類和父類只是叫法不一樣而已。3d
若是繼承的多個類每一個類中都定了相同的函數,那麼那一個會被使用呢? 一、Python的類能夠繼承多個類,Java和C#中則只能繼承一個類 二、Python的類若是繼承了多個類,那麼其尋找方法的方式有兩種,分別是:深度優先和廣度優先指針
當類是經典類時,多繼承狀況下,會按照深度優先方式查找 當類是新式類時,多繼承狀況下,會按照廣度優先方式查找 當前類或者父類繼承了object類,那麼該類即是新式類,不然即是經典類對象
多態blog
多態指的是一類事物有多種形態:動物有多種形態:人,狗,豬 Pyhon不支持Java和C#這一類強類型語言中多態的寫法,可是原生多態,其Python崇尚「鴨子類型」。 Python崇尚鴨子類型,即‘若是看起來像、叫聲像並且走起路來像鴨子,那麼它就是鴨子’ python程序員一般根據這種行爲來編寫程序。例如,若是想編寫現有對象的自定義版本,能夠繼承該對象 也能夠建立一個外觀和行爲像,但與它無任何關係的全新對象,後者一般用於保存程序組件的鬆耦合度。
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') peo=People() pig=Pig() #peo、pig都是動物,只要是動物確定有talk方法 #因而咱們能夠不用考慮它們三者的具體是什麼類型,而直接使用 peo.talk() pig.talk() #能夠定義一個統一的接口來使用 def func(obj): obj.talk() pig=Pig() pig.func(pig)
面向對象總結
問題一:什麼樣的代碼纔是面向對象? 答:從簡單來講,若是程序中的全部功能都是用 類 和 對象 來實現,那麼就是面向對象編程了。 問題二:函數式編程 和 面向對象 如何選擇?分別在什麼狀況下使用? 答:須知:對於 C# 和 Java 程序員來講不存在這個問題,由於該兩門語言只支持面向對象編程(不支持函數式編程)。而對於 Python 和 PHP 等語言卻同時支持兩種編程方式,且函數式編程能完成的操做,面向對象均可以實現;而面向對象的能完成的操做,函數式編程不行(函數式編程沒法實現面向對象的封裝功能)。 因此,通常在Python開發中,所有使用面向對象 或 面向對象和函數式混合使用 面向對象的應用場景: (1)多函數需使用共同的值,如:數據庫的增、刪、改、查操做都須要鏈接數據庫字符串、主機名、用戶名和密碼 (2)須要建立多個事物,每一個事物屬性個數相同,可是值的需求如:張3、李4、楊五, 他們都有姓名、年齡,但其都是不相同。即:屬性個數相同,但值不相同
問題三:類和對象在內存中是如何保存? 答:類以及類中的方法在內存中只有一份,而根據類建立的每個對象都在內存中須要存一份,大體以下圖:
如上圖所示,根據類建立對象時,對象中除了封裝 name 和 age 的值以外,還會保存一個類對象指針,該值指向當前對象的類。 當經過 obj1 執行 【方法一】 時,過程以下: 根據當前對象中的 類對象指針 找到類中的方法 將對象 obj1 看成參數傳給 方法的第一個參數 self
面向對象是一種編程方式,此編程方式的實現是基於對 類 和 對象 的使用 類 是一個模板,模板中包裝了多個「函數」供使用(能夠講多函數中公用的變量封裝到對象中) 對象,根據模板建立的實例(即:對象),實例用於調用被包裝在類中的函數 面向對象三大特性:封裝、繼承和多態
在Python中,如下劃線開頭的變量名和方法名有特殊的含義,尤爲是在類的定義中。用下劃線做爲變量名和方法名前綴和後綴來表示類的特殊成員: _xxx:受保護成員,不能用'from module import *'導入; __xxx__:系統定義的特殊成員; __xxx:私有成員,只有類對象本身能訪問,子類對象不能直接訪問到這個成員,但在對象外部能夠經過「對象名._類名__xxx」這樣的特殊方式來訪問。 注意:Python中不存在嚴格意義上的私有成員。