九道門商業數據分析學院提供
介紹
在學習面向對象的編程時。我決定深入了解它的歷史,結果令人著迷。術語「面向對象程序設計」(OOP)是艾倫·凱(Alan Kay)在1966年讀研究生時提出的。名為Simula的語言是第一種具有面向對象編程功能的程式語言。它是在1967年開發的,用於製作仿真程序,其中最重要的信息稱為對象。
儘管OOP從1960年代初開始進入市場,但在1990年代,由於C ++,OOP開始增長。之後,這種編程技術已被包括Python在內的各種程式語言所採用,如今它的應用幾乎遍及各個領域,例如實時系統,人工智慧和專家系統,客戶端伺服器系統,面向對象的資料庫以及許多其他領域。更多。
因此,在本文中,我將解釋Python中的面向對象編程的基本概念。
表中的內容
什麼是面向對象的編程?面向對象程序設計(OOP)與面向過程程序設計(POP)OOP的主要概念什麼是課程?對象和對象實例化類方法Python類中的繼承封裝形式多態性數據抽象
什麼是面向對象的編程?
面向對象編程(OOP)就是創建「對象」。對象是一組相互關聯的變量和函數。這些變量通常稱為對象的屬性,而功能則稱為對象的行為。這些對象為程序提供了更好,更清晰的結構。
例如,汽車可以是物體。如果我們將汽車視為一個對象,那麼它的屬性就是–它的顏色,模型,價格,品牌等。它的行為/功能將是加速,減速,換檔。
另一個例子-如果我們將狗視為對象,那麼它的屬性將是-他的顏色,他的品種,他的名字,他的體重等。他的行為/功能將是散步,吠叫,嬉戲等。
面向對象編程之所以聞名,是因為它在編程中實現了諸如對象,隱藏,繼承等讀取世界的實體。由於它接近真實場景,因此使可視化變得更加容易。
面向對象程序設計(OOP)與面向過程程序設計(POP)
OOP和過程編程之間的基本區別是-
例如,思考POP的一種方法就是製作檸檬水。製作檸檬水的過程包括:首先根據需要喝水,然後在水中加糖,然後在混合物中加入檸檬汁,最後將整個溶液混合。並且您的檸檬水準備服務。POP以類似的方式要求一定的步驟程序。程序程序由功能組成。這意味著在POP方法中,程序分為特定於不同任務的功能。這些功能按特定順序排列,並且程序控制順序進行。 而OOP程序由對象組成。面向對象的方法將程序劃分為多個對象。這些對象是捆綁了真實對象的屬性和行為的實體。POP僅適用於小型任務。因為隨著程序長度的增加,代碼的複雜度也會增加。最終變成了功能網。而且,它變得難以調試。OOP藉助更清晰,更簡單的結構解決了這個問題。它允許以繼承的形式重用代碼。另一個重要的事情是,在面向過程的編程中,所有功能都可以訪問所有數據,這意味著缺乏安全性。假設您要保護憑據或來自世界各地的任何其他關鍵信息。然後,程序方法無法為您提供這種安全性。為此,OOP藉助其驚人的功能之一「 封裝」幫助您,該功能使我們可以隱藏數據。不用擔心,我將在本文的後半部分以及其他面向對象編程的概念中對此進行詳細介紹。現在,只需要了解OOP就可以實現安全性,而POP則不能。諸如C,Pascal和BASIC之類的程式語言都使用過程方法,而Java,Python,JavaScript,PHP,Scala和C ++是提供面向對象方法的主要語言。主要的Python OOP概念-
在本節中,我們將深入研究OOP的基本概念。我們將涵蓋以下主題-
類目的方法遺產封裝形式多態性數據抽象1.什麼是班級?
這個問題的直接答案是-類是對象的集合。與原始數據結構不同,類是用戶定義的數據結構。它們使代碼更易於管理。
讓我們看看如何在下面定義一個類-
類class_name: 班級機構
我們在class_name和分號後定義一個帶有關鍵字「 class」的類。我們考慮將縮進作為其主體之後在此基礎上編寫的所有內容。為了使它更容易理解,我們來看一個例子。
考慮一個汽車展示廳的情況。您要存儲每輛車的詳細信息。首先定義一個類
車類: 通過
而已!
注意:我使用pass語句代替它的主體,因為主要目的是顯示如何定義一個類,而不是它應該包含的內容。
在詳細介紹之前,首先要了解對象和實例化。
2.對象和對象實例化
當我們定義一個類時,僅創建對象的描述或藍圖。在創建對象之前沒有內存分配。在反對者 實例包含實際數據或信息。
實例化不過是創建類的新對象/實例。讓我們創建上面定義的類的對象-
obj1 = Car()
完成了!請注意,您可以根據自己的選擇更改對象名稱。
嘗試列印該對象-
列印(obj1)
由於我們的類為空,因此它返回存儲對象的地址,即0x7fc5e677b6d8
在繼續前進之前,您還需要了解班級指揮。
類構造器
到目前為止,我們有一個空的Car類,是時候用汽車的屬性來填充我們的類了。類構造器的工作是在創建類的對象時將值分配給類的數據成員。
汽車可能具有各種屬性,例如其名稱,顏色,型號,品牌名稱,發動機功率,重量,價格等。出於理解目的,我們僅選擇其中一些。
車類: def __init __(自身,名稱,顏色): self.name =名稱 self.color =顏色
因此,汽車或任何其他對象的屬性必須在我們稱為__init __()的方法內。此__init __()方法也稱為構造方法。每當構造類的對象時,我們都調用構造函數方法。
現在讓我們談談__init __()方法的參數。因此,此方法的第一個參數必須是self。然後,剩下的參數只會出現。
構造函數方法中的兩個語句是–
self.name =名稱self.color =顏色:這將創建新的屬性,即名稱和顏色,然後為它們分配相應參數的值。「 self」關鍵字表示該類的實例。通過使用「 self」關鍵字,我們可以訪問類的屬性和方法。它在方法定義和變量初始化中很有用。每當我們定義一個方法時,都會明確使用「自我」。
注意:您也可以在此__init __()方法之外創建屬性。但是這些屬性對於整個類都是通用的,因此您必須為它們分配值。
假設陳列室中的所有汽車都是轎車,而不是一遍又一遍地指定,您可以通過在__init __()外部創建一個屬性來將car_type的值固定為轎車。
車類: car_type =「轎車」 #class屬性 def __init __(自身,名稱,顏色): self.name =名稱#instance屬性 self.color =顏色#instance屬性
在這裡,實例屬性指的是構造函數方法中的屬性,即self.name和self.color。並且,Class屬性是指構造函數方法外部的屬性,即car_type。
3.類方法
到目前為止,我們已經添加了汽車的屬性。現在是時候添加一些行為了。方法是我們用來描述對象行為的功能。它們也在類內定義。看下面的代碼-
車類: car_type =「轎車」 def __init __(個人,姓名,裡程): self.name =名稱 self.mileage =裡程 def說明(自己): return f「 {self.name}汽車的行駛裡程為{self.mileage} km / l」 def max_speed(self,speed): 返回f「 {self.name}以{speed} km / hr的最大速度運行」
在類中定義的除構造方法之外的方法稱為實例方法。此外,我們有兩個實例方法這裡- 說明()和MAX_SPEED()。讓我們逐一談論它們-
description()-此方法返回一個字符串,其中包含汽車的描述,例如名稱和行駛裡程。此方法沒有其他參數。此方法使用實例屬性。max_speed()-此方法有一個附加參數,並返回一個顯示汽車名稱及其速度的字符串。請注意,附加參數速度未使用「 self」關鍵字。由於speed不是實例變量,因此我們不使用self關鍵字作為其前綴。讓我們為上述類創建一個對象。
obj2 = Car(「 Honda City」,24.1)列印(obj2.description())列印(obj2.max_speed(150))
我們要做的是創建一個car類的對象,並傳遞了必需的參數。為了訪問實例方法,我們使用object_name.method_name()。
方法description()沒有任何其他參數,因此在調用它時沒有傳遞任何參數。
max_speed()方法有一個附加參數,因此我們在調用它時傳遞了一個參數。
注意:要記住的三件重要事情是:
您可以創建一個類的任意數量的對象。如果該方法需要n個參數,而您沒有傳遞相同數量的參數,則將發生錯誤。參數的順序很重要。讓我們一一看
創建一個類的多個對象車類: def __init __(個人,姓名,裡程): self.name =名稱 self.mileage =裡程 def max_speed(self,speed): 返回f「 {self.name}以{speed} km / hr的最大速度運行」本田=汽車(「本田城」,21.4) 列印(Honda.max_speed(150)) 斯柯達=汽車(「斯柯達明銳」,13) 列印(Skoda.max_speed(210))
傳遞了錯誤數量的參數。車類: def __init __(個人,姓名,裡程): self.name =名稱 self.mileage =裡程本田=汽車(「本田城」) 印刷(本田)
由於我們沒有提供第二個參數,因此出現了此錯誤。
參數順序車類: def __init __(個人,姓名,裡程): self.name =名稱 self.mileage =裡程 def說明(自己): return f「 {self.name}汽車的行駛裡程為{self.mileage} km / l」本田=汽車(24.1,「本田城」) 列印(Honda.description())
弄亂!注意,我們更改了參數的順序。
現在,有四個面向對象編程的基本概念- 繼承,封裝,多態和數據抽象。了解所有這些對於理解OOP非常重要。到目前為止,我們已經涵蓋了OOP的基礎知識,讓我們進一步深入。
4. Python類中的繼承
繼承是一個類繼承另一個類的屬性和方法的過程。繼承其屬性和方法的類稱為Parent類。從父類繼承屬性的類是Child類。
有趣的是,連同繼承的屬性和方法,子類可以具有自己的屬性和方法。
如何繼承父類?使用以下語法:
class parent_class:父類的主體class child_class(parent_class):兒童班的身體
讓我們看一下實現-
車級:#父級 def __init __(個人,姓名,裡程): self.name =名稱 self.mileage =裡程 def說明(自己): return f「 {self.name}汽車的行駛裡程為{self.mileage} km / l」 寶馬(汽車)級:#兒童級 通過 奧迪(汽車)類:#兒童類 def audi_desc(): 返回「這是奧迪類的描述方法。」
obj1 = BMW(「 BMW 7-series」,39.53) 列印(obj1.description()) obj2 = Audi(「 Audi A8 L」,14) 列印(obj2.description()) 列印(obj2.audi_desc())
我們創建了兩個子類「 BMW」和「 Audi」,它們繼承了父類「 Car」的方法和屬性。在BMW類中,我們沒有提供其他功能和方法。而在Audi類中的另一種方法。
注意子類的對象如何在obj1.description()和obj2.description()的幫助下訪問父類的實例方法description()。而且,也可以使用obj2.audi_desc()訪問Audi類的單獨方法。
5.封裝
正如我在本文的第一部分中提到的,封裝是一種確保安全性的方法。基本上,它隱藏了外部人無法訪問的數據。例如,如果組織希望保護對象/信息免受客戶端或任何未授權人員的有害訪問,則封裝是確保這一點的方法。
您可以在方法或屬性名稱之前使用單個下劃線(_)聲明受保護的方法或屬性。如-self._name或def _method(); 這兩行都表明屬性和方法是受保護的,不應在類和子類的訪問權限之外使用,而是可以由類方法和對象訪問。
儘管Python只是將_用作編碼約定,但它告訴您應在類範圍內使用這些屬性/方法。但是您仍然可以像往常一樣訪問定義為保護的變量和方法。
現在,實際上是為了防止從類範圍之外訪問屬性/方法,可以使用「 私有成員 」。為了將屬性/方法聲明為私有成員,請在前綴中使用雙下劃線(__)。如– self .__ name或def __method(); 這兩行都表明屬性和方法是私有的,並且無法從類外部進行訪問。
類車: def __init __(個人,姓名,裡程): self._name =名稱#受保護的變量 self.mileage =裡程 def說明(自己): return f「 {self._name}汽車的行駛裡程為{self.mileage} km / l」
obj = car(「寶馬7系列」,39.53) #通過類方法訪問受保護的變量 列印(obj.description()) #直接從外部訪問受保護的變量 列印(obj._name) 列印(obj.mileage)
注意我們如何訪問受保護的變量而沒有任何錯誤。顯然,對該變量的訪問仍然是公共的。讓我們看看封裝的工作原理-
車類: def __init __(個人,姓名,裡程): self .__ name = name#私有變量 self.mileage =裡程 def說明(自己): return f「 {self .__ name}汽車的行駛裡程為{self.mileage} km / l」
obj = Car(「 BMW 7-series」,39.53) #通過類方法訪問私有變量 列印(obj.description()) #直接從外部訪問私有變量 列印(obj.mileage) 列印(obj .__ name)
當我們嘗試使用description()方法訪問私有變量時,沒有遇到任何錯誤。但是,當我們嘗試直接在類外部訪問私有變量時,Python給了我們一個錯誤說明:car對象沒有屬性'__name'。
您仍然可以使用其變形的名稱直接訪問此屬性。名稱修飾 是我們用於從外部訪問類成員的一種機制。Python解釋器會將帶有「 __var」的任何標識符重寫為「 _ClassName__var」。使用此方法,您還可以從外部訪問該類成員。
車類: def __init __(個人,姓名,裡程): self .__ name = name#私有變量 self.mileage =裡程 def說明(自己): return f「 {self .__ name}汽車的行駛裡程為{self.mileage} km / l」
obj = Car(「 BMW 7-series」,39.53) #通過類方法訪問私有變量 列印(obj.description()) #直接從外部訪問私有變量 列印(obj.mileage) print(obj._car__name)#被纏住的名字
請注意,規則修改的設計主要是避免發生意外。但是仍然可以訪問或修改被視為私有的變量。這在特殊情況下(例如在調試器中)甚至很有用。
6.多態性
這是希臘字。如果我們打破「多態」一詞,就會得到「多」形和「變形」形。因此,多態性意味著具有多種形式。在OOP中,它是指名稱相同但功能不同的功能。
奧迪課程: def說明(自己): print(「這是AUDI類的描述功能。」) 寶馬級: def說明(自己): print(「這是BMW類的描述功能。」)
奧迪=奧迪() 寶馬=寶馬() 用於(奧迪,寶馬)中的汽車: car.description()
當使用對象audi調用該函數時,將調用Audi類的函數,而使用對象bmw調用該函數時,將調用BMW類的函數。
7.數據抽象
我們使用抽象來隱藏函數的內部細節或實現並僅顯示其功能。這類似於您在不知道背景機制的情況下如何駕駛汽車的方式。或者,您知道如何使用開關打開或關閉電燈,但是您不知道插座後面發生了什麼。
具有至少一個抽象功能的任何類都是抽象類。為了首先創建一個抽象類,您需要從abc模塊導入ABC類。這使您可以在其中創建抽象方法。ABC代表抽象基類。
從abc導入ABC 類abs_class(ABC): 類的主體
重要的是 –您不能使用abstract方法為abstract類創建對象。例如-
從abc導入ABC,abstractmethod 轎車(ABC): def __init __(self,name): self.name =名稱 @abstractmethod 定義價格(自我,x): 通過
obj =汽車(「本田城」)
現在的問題是我們如何準確地使用這種抽象。答案是通過使用繼承。
從abc導入ABC,abstractmethod 轎車(ABC): def __init __(self,name): self.name =名稱 def說明(自己): print(「這是汽車的描述功能。」) @abstractmethod 定義價格(自我,x): 通過 新車類(汽車): 定義價格(自我,x): print(f「 {self.name}的價格為{x}十萬。」)
obj = new(「 Honda City」) obj.description() obj.price(25)
Car是從abc模塊的ABC類繼承的抽象類。請注意,我在抽象類中有一個抽象方法(price())和一個具體方法(description())。這是因為抽象類可以同時包含這兩種功能,而普通類則不能。從該抽象類繼承的另一個類是new()。此方法為抽象方法(price())定義,這是我們使用抽象函數的方式。
用戶從new()類創建對象並調用price()方法後,new()類內部的price方法的定義就會起作用。這些定義對用戶隱藏。Abstract方法只是提供一個聲明。子類需要提供定義。
但是,當為new()類(即obj)的對象調用description()方法時,將調用Car的description()方法,因為它不是抽象方法。
尾注
總而言之,在本文中,我介紹了Python中面向對象編程的基本概念。
希望您了解這些文章中介紹的概念。如果您有任何疑問,請在下面的評論中告訴我。