程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python學習三(面向對象)

編輯:Python

1.面向對象和面向過程

        面向過程就是所有的事情已過程為主,關注的重點是過程,即第一步、第二步、第三步是什麼。C語言就是典型的面向過程的語言。C語言需要只要先找到main函數,在main函數中一步一步的往下執行,比如如下代碼:

Print('step1')
print('step2')
print('step3')

        面向對象關注點則是對象。比如一個人是一個對象,這個人身高、體重就是對象的屬性,而跑、跳則是這個對象可以執行的相關操作。比如如下代碼:

class 類名:
def 方法1();
def 方法2():

        簡而言之,編寫函數就是“面向過程”編寫類就是“面向對象”

2.類和對象

        對象:具有行為屬性。在進行描述的時候,屬性多為名字。行為多為動詞。

        :指一個類別。具有相同屬性和行為的“對象”構成的一個整體。

        類和對象之間的關系:

        類是對象的抽象表現,對象是類的具體表現

        類是設計的藍圖,對象是根據藍圖設計出來的具體產物。

3.類的定義      

        在Python中,通過class關鍵字來定義一個類。這個類中可以包含零個多個屬性和方法

class 類名:
def 方法1();
def 方法2():

 4.類的實例-對象

        當可以實現一個類之後,就可以通過這個類來實例化一個對象。這個對象包含了這個類的全部屬性和方法

class person: #類
def a_name(self): #方法
print('xiaoming')
xiaoming = person() #根據person類實例一個對象
xiaohong = person() #根據person類實例一個對象
zhangsan = person() #根據person類實例一個對象
xiaoming.a_name() #調用對象的方法
xiaohong.a_name() #調用對象的方法
zhangsan.a_name() #調用對象的方法
結果:
xiaoming
xiaoming
xiaoming

5.動態增加屬性和方法

        很多時候我們需要根據需求給對象添加特殊的屬性或方法,而這些屬性和方法又不能跟其他對象共用,此時就需要動態來添加屬性和方法了。

class person: #類
def a_name(self): #方法
print('xiaoming')
def age(self): #動態增加的方法
print("18")
xiaoming = person() #根據person類實例一個對象
xiaohong = person() #根據person類實例一個對象
zhangsan = person() #根據person類實例一個對象
xiaoming.gender = 'boy' #動態增加屬性gender
xiaoming.age = age #動態增加方法age
xiaoming.a_name() #調用對象的方法
xiaohong.a_name() #調用對象的方法
zhangsan.a_name() #調用對象的方法
print(xiaoming.gender)
xiaoming.age(xiaoming)
print(zhangsan.gender)
zhangsan.age(zhangsan)
結果:
xiaoming
xiaoming
xiaoming
boy
18
Traceback (most recent call last):
File "d:/python/test_project/test.py", line 37, in <module>
print(zhangsan.gender)
AttributeError: 'person' object has no attribute 'gender'
Traceback (most recent call last):
File "d:/python/test_project/test.py", line 38, in <module>
zhangsan.age()
AttributeError: 'person' object has no attribute 'age'

6.init(self)函數

        在python的init函數中,init前後各有2個下劃線。而Init在每次被調用創建對象時,都會“自動調用”一次。參數self是必不可少的。類中定義的方法,第一個參數是固定的,命名為"self"。

class person: #類
def __init__(self):
print("init")
def a_name(self): #方法
print('xiaoming')
xiaoming = person() #根據person類實例一個對象
xiaohong = person() #根據person類實例一個對象
zhangsan = person() #根據person類實例一個對象
結果:
init
init
init

7.傳入參數賦值屬性

        很多時候,每個對象的屬性值都是不相同的,就比如我們上邊的代碼,創建一個“名字”的方法,但是這個方法打印的內容都是相同的。這樣就沒有版本區分不同的對象了。所以,我們可以通過傳入參數的方式賦值不同的屬性值。

class person: #類
def __init__(self,name,age):
self.name = name #屬性
self.age = age #屬性
def action(self): #方法
print('%s is running,age %d' %(self.name,self.age))
xiaoming = person('xiaoming',18) #根據person類實例一個對象
zhangsan = person('zhangsan',20) #根據person類實例一個對象
xiaoming.action() #對象執行方法
zhangsan.action() #對象執行方法
結果:
xiaoming is running,age 18
zhangsan is running,age 20

8.類屬性

        類屬性與當前類有綁定關系,與當前類創建的對象無關系

        對於類屬性可以通過類名進行訪問,也可以通過對象進行訪問。但是,通過對象進行訪問,是“只讀”,不能進行修改

        對於實例屬性,只能通過創建的對象進行訪問不能通過類名進行訪問

class person: #類
city = 'beijing' #類屬性
def __init__(self,name,age):
self.name = name
self.age = age
def action(self): #方法
print('%s is running,age %d' %(self.name,self.age))
xiaoming = person('xiaoming',18) #根據person類實例一個對象
zhangsan = person('zhangsan',20) #根據person類實例一個對象
print(person.city) #打印類屬性
xiaoming.city = 'shanghai' #通過對象修改類屬性
print(xiaoming.city) #打印對象類屬性
print(person.city) #打印類屬性
print(zhangsan.city) #打印對象類屬性
print('>>>>>>>>>>>>>>')
person.city = 'nanjing'
print(xiaoming.city) #打印對象類屬性
print(person.city) #打印類屬性
print(zhangsan.city) #打印對象類屬性
結果:
beijing
shanghai
beijing
beijing
>>>>>>>>>>>>>>
shanghai
nanjing
nanjing

        從上述代碼中,通過對象修改了類屬性,看似修改成功了,其實並不是修改了類屬性,只是動態地給對象創建了一個屬性“city”,只不過這個屬性名跟類屬性的"city"屬性名名字相同罷了。

9.類方法

        類方法需要使用@classmethod修飾

        類方法的第一個參數是固定的,命名為cls

        有兩種方式來訪問類方法,一種是通過類名來訪問,另一種是通過對象名來訪問不建議)。

        最好是通過類方法來訪問類屬性通過實例方法來訪問實例屬性

class person: #類
city = 'beijing' #類屬性
def __init__(self,name,age):
self.name = name
self.age = age
def action(self): #方法
print('%s is running,age %d' %(self.name,self.age))
@classmethod
def move_city(cls,city): #類方法
cls.city = city
xiaoming = person('xiaoming',18) #根據person類實例一個對象
zhangsan = person('zhangsan',20) #根據person類實例一個對象
print(person.city)
person.move_city('shenzhen') #通過類名訪問
print(person.city)
xiaoming.move_city("guangzhou") #通過對象名訪問
print(person.city)
結果:
beijing
shenzhen
guangzhou

10.私有變量(private)

        如果希望類中的屬性為私有屬性,可以通過在屬性名稱前加兩個下劃線__來實現。此時只能通過內部進行訪問外部不能訪問

class person: #類
city = 'beijing' #類屬性
def __init__(self,name,age):
self.__name = name #私有屬性
self.__age = age #私有屬性
def action(self): #方法
print('%s is running,age %d' %(self.name,self.age))
def get_name(self): #訪問私有屬性
print(self.__name)
def get_age(self): #訪問私有屬性
print(self.__age)
xiaoming = person('xiaoming',18) #根據person類實例一個對象
zhangsan = person('zhangsan',20) #根據person類實例一個對象
xiaoming.get_name()
xiaoming.get_age()
結果:
xiaoming
18

        如果直接調用實例進行訪問的話,則會報錯

print(xiaoming.__name)
結果:
Traceback (most recent call last):
File "d:/python/test_project/test.py", line 38, in <module>
print(xiaoming.__name)
AttributeError: 'person' object has no attribute '__name'

        那為什麼要設置私有變量呢?因為這樣可以在方法中對傳入的參數進行判斷,避免無效的參數輸入

class person: #類
def __init__(self,name,age):
self.__name = name #私有屬性
self.__age = age #私有屬性
def set_age(self,s_age):
if not isinstance(s_age,(int)):
raise TypeError('age false type')
if(s_age > 0 and s_age < 100):
self.__age = s_age
print('age %d' %self.__age)
else:
print('age not correct:%d' %s_age)
xiaoming.set_age(18)
xiaoming.set_age(200)
xiaoming.set_age('18')
結果:
age 18
age not correct:200
Traceback (most recent call last):
File "d:/python/test_project/test.py", line 52, in <module>
xiaoming.set_age('18')
File "d:/python/test_project/test.py", line 29, in set_age
raise TypeError('age false type')
TypeError: age false type

11.繼承

        當有兩個屬性高度類似的類時,就可以使用繼承。如果類A繼承了類B,那麼A就是子類,B就是父類。子類一旦繼承了父類,那麼子類就會具備父類的一切特征。因此,父類能做的事情,子類也都可以做。

class fater: #父類
def __init__(self):
self.name = 'fater'
self.age = 58
class child(fater): #子類
def __init__(self):
super().__init__() #調用父類的init方法
self.gender = 'boy'
laowang = fater(); #實例父類
print(laowang.name) #打印父類屬性
xiaowang = child(); #實例子類
print(xiaowang.name) #打印子類繼承父類的屬性
print(xiaowang.gender) #打印子類特有的屬性
print(laowang.gender) #打印父類中子類的屬性(報錯)
結果:
fater
fater
boy
Traceback (most recent call last):
File "d:/python/test_project/test.py", line 64, in <module>
print(laowang.gender)
AttributeError: 'fater' object has no attribute 'gender'

12.多重繼承

        有時一個對象需要繼承多個父類的屬性,這就是多重繼承。

class fater: #父類
def __init__(self,name,age):#屬性
self.name = name
self.age = age
def get_name(self):#方法
print('fater name:%s' %self.name)
class mother: #父類
def __init__(self,name,age) -> None: #屬性
self.name = name
self.age = age
def get_name(self):#方法
print('mother name:%s' %self.name)
class child(fater,mother):#子類,按照先後順序進行繼承
def __init__(self, name, age):#屬性
super().__init__(name, age) #調用父類的init方法
self.gender = 'boy'
ft = fater('laowang',58); #實例
mt = mother('laohong',55) #實例
kid = child('xiaoming',10) #實例
print(ft.name)
print(mt.name)
print(kid.name) #父類屬性
print(kid.age) #父類屬性
print(kid.gender) #子類屬性
kid.get_name() #父類方法
結果:
laowang
laohong
xiaoming
10
boy
fater name:xiaoming

        可以看到,雖然同時繼承了father和mother,但是調用父類的"name"方法時,調用的還是fater的方法。因為在繼承時,father在前

        那把mother改到前面後試試。

class child(mother,fater):#子類,按照先後順序進行繼承
結果:
mother name:xiaoming

13.多態

class fater: #父類
def __init__(self,name,age):#屬性
self.name = name
self.age = age
def get_name(self):#方法
print('fater name:%s' %self.name)
class child(fater):#子類
def __init__(self, name, age):#屬性
super().__init__(name, age) #調用父類的init方法
self.gender = 'boy'
def get_name(self):
print('child name:%s' %self.name)
ft = fater('laowang',58); #實例
kid = child('xiaoming',10) #實例
kid.get_name()
結果:
child name:xiaoming

        可以看到,child是從father處繼承了屬性和方法,child和father有同名的方法get_name,但是當調用child的get_name方法時,會自動調用自身的方法,而不會調用父類的方法。這就是多態。

        對於一個變量,只需要知道父類型,無需確切地知道它的子類型,就可以放心地調用方法,而具體調用的方法是作用在father還是child,由運行時該對象的確切類型決定,這就是多態的威力。調用方只管調用,不管細節,而當需要新增一種子類型是,只要確保方法編寫正確,不用管原來的代碼是如何調用的。這就是著名的“開閉”原則。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved