|
文章目錄
- 面向對象編程
- 1. 什么是面向對象
- 2. 類(class)
- 3. 類的實例
- 關于self
- 4. 對象的初始化
- 5. `__str__`
- 6. 類之間的關系
- 繼承關系
- 組合關系
- 7. 補充練習

面向對象編程
1. 什么是面向對象
面向對象編程是一種編程思想,它將現實世界的概念和關系映射到代碼中.
在面向對象編程中,我們通過創建對象來表示現實世界中的事物,并通過定義對象的屬性和方法來描述它們的狀態和行為.
面向對象編程強調了代碼的模塊化、封裝、抽象、繼承和多態等概念.
例如, 在現實世界中我們需要去記錄一名學生的基本信息, 如果使用文本來記錄: 例如
有一名學生叫張三, 來自北京, 性別男. 這樣可以輕松記錄一名學生的信息.
但是使用如下表格, 結構會更加的清晰.
姓名 | 張三 |
---|---|
年齡 | 20 |
籍貫 | 北京 |
性別 | 男 |
在現實世界中我們需要去記錄一輛車的基本信息, 需要用到如下表格:
品牌 | |
---|---|
型號 | |
排量 | |
車架號 |
上述都表格都可以很清晰的描述學生和車輛的基本信息.
表格相當于是 一個藍圖或者模板. 每個學生都可以拿著這個表格, 填寫自己對應的信息, 在程序中, 上面的表格就相當于是一個類, 通過這個類可以創建多個學生對象.
2. 類(class)
類和對象是面向對象編程的核心概念.
類是一個抽象的概念,用于描述對象的屬性(數據)和方法(行為).
對象則是類的具體實例,表示一個具體的實體.
類(class)
類是一種模板或藍圖,用于創建對象.它定義了對象的屬性和方法,描述了對象的狀態和行為.類通過定義一組相關的屬性和方法來封裝數據和操作,從而提供了一種組織和管理代碼的方式.
Python 中的一切對象都有各自的類型,比如:
整數對象 的類型是 int
字符串對象 的類型是 str
列表對象 的類型是 list
元組對象 的類型是 tuple
字典對象 的類型是 dict
Python 的內置函數type可以查看對象的類型:
>>> type(12)
<class 'int'> # 整數類型
>>> type('12')
<class 'str'> # 字符類型
>>> type([1,2])
<class 'list'> # 列表類型
>>> type((1,2))
<class 'tuple'> # 元組類型
>>> type({1:2})
<class 'dict'> # 字典類型
我們掌握了這些內置的數據類型,通常就可以開發Python程序了.
但是當我們要開發的軟件系統 更加復雜的時候,尤其是系統里面的對象 和現實世界的對象 存在對應關系的時候,如果只能用這些內置類型,就會感覺很不方便.
比如,我們的程序要表示一個 奔馳汽車 這樣的對象類型,屬性有:品牌,國家,價格.
如果只用Python的內置類型,大家想想怎么表示.
當然,我們可以定義一個字典類型的對象,比如:
benzCar = {'brand' : '奔馳','country' : '德國','price' : 300000
}
如果這個汽車對象還需要有自己特定的行為,比如 按喇叭會發出嘟嘟的聲音。那又該怎么定義呢?
有人說,可以定義一個函數對象作為它的屬性,像這樣:
def pressHorn():print('嘟嘟~~~~~~')benzCar = {'brand' : '奔馳','country' : '德國','price' : 300000,'pressHorn' : pressHorn # 字典對象的值可以是一個函數對象
}# 我可以這樣執行它的行為
benzCar['pressHorn']()
似乎也可以.
但是這里 benzCar 更像是一個具體的對象,并不是一種 對象類型.
而且 這個 benzCar 汽車的 行為的定義 ,要在外面定義一個函數, 然后benzCar字典的內部去引用它,這樣也比較麻煩.
為了解決這樣的普遍問題,Python語言可以讓我們 自己定義對象類型.
Python中自定義對象類型,就是 定義一個類 , 類 就是 類型 的意思.
比如 : 奔馳汽車, 可以這樣定義:
使用 class
關鍵字定義一個類.類名通常使用大寫字母開頭,遵循大駝峰命名規范.
class BenzCar: brand = '奔馳' # 品牌屬性country = '德國' # 產地屬性@staticmethoddef pressHorn(): print('嘟嘟~~~~~~')
定義一個類 用關鍵字 class 后面加 類的名稱.
類名的規范 和 變量命名規范一樣。 通常我們會把類名 首字母大寫, 這里定義的類名就是 BenzCar
下面定義的 brand, country 都是 BenzCar 類的 屬性.
這種屬性被稱為類屬性
如果我們要得到屬性的值可以這樣用 類名.屬性名 的方式,如下
print(BenzCar.brand)
而 pressHorn 則是該類型的一個 方法.
請注意上面的 @staticmethod 的修飾, 說明這是該類的一個 靜態方法
要調用執行該類的靜態方法,像這樣就可以了:
BenzCar.pressHorn()
類的屬性
類的屬性是與類相關聯的數據,用于描述對象的特征或狀態.
類的屬性可以通過類名或對象訪問.
類屬性在類級別上定義,被所有類的實例共享.
類屬性的定義實際上就是寫在類中的變量.
(成員變量) - 注意不是實例屬性哦
class Student:name = '張三'age = 0
在上面的示例中, Student類定義了2個類屬性, name
和age
,它被所有Student類的實例共享. 類屬性可以通過類名或者實例對象訪問.
class Student:name = '張三'age = 18# 類屬性可以通過**類名或者實例對象**訪問print(Student.name)print(Student.age)print("-----------------------------")stu = Student()print(stu.name)print(stu.age)
類的方法
類的方法是與類相關聯的函數,用于定義對象的行為.方法在類中定義,并通過對象調用.方法可以訪問和操作對象的屬性.
class Student:name = '張三'age = 0def introduce(self):print(f'大家好, 我的名字叫{self.name}, 今年{self.age}歲')def study(self):print(f'{self.name}正在努力學習.')stu = Student()stu.introduce()stu.study()
以上示例在Student
類中定義了2個方法, introduce
和study
. 用于定義對象的2個行為: 自我介紹和學習.
上述示例中方法中第一個形參是self
的方法叫做實例方法
. 類屬性可以通過實例對象self來訪問.
3. 類的實例
Python中 類 是 某種對象的類型.
比如 int 是 整數對象的類型, str是字符串對象的類型, list是 列表對象的類型.
我們把一個個具體的 對象稱為 該類型的 實例,
比如,我們可以說
數字對象 3 是 int 類型的的實例,具有int類型的特征
字符串對象 ‘abc’ 是 str 類型的實例,具有str類型的特性(比如可以執行str的所有方法,比如 find, split等)
列表對象 [1,2,3] 是 list 類型的的實例,具有list類型的特性(比如可以執行list的所有方法,比如 reverse,append等)
同樣的,我們自定義的類,也可以產生該類的實例對象. 每個實例對象就是該類的一個實例,具有該類的一切特征.
要產生一個類的實例對象,只需要 在類名后面加上括號,就可以了,就會返回一個該類的實例對象.
比如:
car1 = BenzCar()
car1 變量就對應了一個 BenzCar 類型 的實例對象,具有 BenzCar 類的一切屬性和方法.大家可以執行下面的代碼試試。
class BenzCar: brand = '奔馳' country = '德國' @staticmethoddef pressHorn(): print('嘟嘟~~~~~~')car1 = BenzCar()
print(car1.brand)
car1.pressHorn()
同樣,我們也可以用 type 函數查看 car1 這個實例的類型,如下所示:
>>> type(car1)
<class '__main__.BenzCar'>
說明 car1 是 __main__ 模塊里面定義的 BenzCar 類型.
大家一定要搞清楚 類 和 實例 的關系.
比如 :
人 就是 一個 類, 而 關羽、張飛 就是 人 這個類的 具體實例.
狗 也是 一個 類, 而 你們家的阿黃 和 隔壁家的旺財 就是狗 這個類的 具體實例.
Python中 定義一個類型 就是描述 這些類型的實例的 公共特征. 后面根據這個類創建的實例 都具有這個類的 特征,就是 具體什么 屬性、方法.
在面向對象編程中,類的對象(Class Object)是類的具體實例, 所以類的對象也叫做實例對象.類定義了對象的屬性和方法,而對象是類的實體,具有自己的屬性值和對類中方法的訪問權限.
實例屬性和實例方法
剛才我們定義的類里面的屬性都是 類屬性 ,里面的方法都是類的 靜態方法 .
所有BenzCar類的實例對象,其 品牌名 brand ,對應的類屬性應該是相同的.
就是說下面這樣的兩個實例:
car1 = BenzCar()
car2 = BenzCar()
car1 和 car2 的 brand屬性 都是一樣的 值, 都是字符串 ‘奔馳’
很好理解,因為品牌這樣的屬性 對于所有的 奔馳車都是一樣的,都是 ‘奔馳’.
類屬性 是類的共同特征屬性.
但是有些屬性,比如顏色、發動機編號 是每一輛奔馳車 都不同的.
所以,在我們定義的 類BenzCar 里面, 顏色、發動機編號 是 不應該 作為類屬性的.
每個實例獨有的屬性,稱之為 類的實例屬性
實例屬性通常是在類的 初始化方法 init 里面定義的.
比如:
class BenzCar: brand = '奔馳' country = '德國' @staticmethoddef pressHorn(): print('嘟嘟~~~~~~')# 初始化方法, 注意前后各有兩個下劃線def __init__(self):self.color = 'red' # 顏色self.engineSN = '837873398' # 發動機編號
上面的初始化方法 __init__ ,就創建了兩個實例屬性 color 和 engineSN。
為什么 __init__ 方法 叫初始化方法呢?
解釋器在執行 像下面這樣的 實例化類對象 的代碼時,
car1 = BenzCar()
首先,解釋器會 在內存中 創建一個該類 的 實例對象;
然后,解釋器會查看這個類是否有 __init__方法,如果有,就會去調用它.
__init__ 是 創建好實例后 立即就要 執行 的方法,所以稱之為初始化方法.
通常我們會在__init__方法里面 執行一些初始化的動作,主要就是創建該實例的 實例屬性.
__init__ 方法的第一個參數是 self, 它 是干什么用的呢?
剛才說了, 解釋器執行實例化代碼,會先在內存中創建該類實例對象,然后調用類 的__init__方法.
調用 __init__方法時,就將實例對象 傳遞給 self參數.
self 參數變量 指向的 就是 實例對象 本身
, 所以下面的代碼就是創建該實例的屬性color 和 engineSN 了
self.color = 'red' # 顏色
self.engineSN = '8378738398' # 發動機編號
類的靜態方法要在方法定義 上面加上 @staticmethod 的修飾.
而 類的 實例方法 不需要任何修飾.
通常類的實例方法,都是要 訪問類的實例屬性的. 包括: 創建、修改、刪除 類的實例屬性.
因為 實例方法 就是要操作 實例獨有的屬性,否則不操作任何實例屬性的話,就應該定義為 類方法.
比如 __init__ 初始化方法,就是一個實例方法,它通常要創建一些實例屬性.
而 pressHorn 方法是類的靜態方法, 靜態方法是不能訪問實例屬性的.
有時候,實例屬性的取值,不是固定寫在初始化方法的代碼里面.
比如這里,每輛車的顏色、發動機號都是不同的,我們應該作為參數傳進去.
所以修改代碼為這樣:
class BenzCar: brand = '奔馳' country = '德國' @staticmethoddef pressHorn(): print('嘟嘟~~~~~~')def __init__(self,color,engineSN):self.color = color # 顏色self.engineSN = engineSN # 發動機編號
這樣我們在創建實例的時候,就可以根據需要指定不同的實例屬性了,比如:
car1 = BenzCar('白色','24503425527866')
car2 = BenzCar('黑色','34598423586877')
print(car1.color)
print(car2.color)
print(car1.engineSN)
print(car2.engineSN)
雖然定義的時候, init 方法 有3個參數 : self,color,engineSN
但是我們這樣調用 BenzCar() 實例化的時候, 只需要傳入后面兩個參數即可,
因為self 參數 需要傳入實例對象本身,解釋器會自動幫我們傳入.
其它的 實例方法也是這樣, 比如我們定義一個 修改車身顏色的方法 changeColor:
class BenzCar: brand = '奔馳' country = '德國' @staticmethoddef pressHorn(): print('嘟嘟~~~~~~')def __init__(self,color,engineSN):self.color = color # 顏色self.engineSN = engineSN # 發動機編號def changeColor(self,newColor):self.color = newColorcar1 = BenzCar('白色','24503425527866')
car1.changeColor('黑色')print (car1.color)
調用 changeColor方法的時候,只需要傳入參數 newColor 對應新的顏色即可.
不需要我們傳入self參數,self 參數是實例對象本身,解釋器會自動幫我們傳入.
注意: 如果你的實例屬性名稱 和 靜態屬性(類屬性) 重復了 ,通過類實例訪問該屬性,訪問的是實例屬性通過類名訪問該屬性,訪問的是類屬性.
比如:
class Car:brand = '奔馳'name = 'Car'def __init__(self):# 可以通過實例訪問到類屬性print(self.brand)# 定義實例屬性和類屬性重名self.name = 'benz car'c1 = Car()print(f'通過實例名訪問name:{c1.name}')
print(f'通過類名 訪問name:{Car.name}')
一旦創建了 和類屬性同名的 實例屬性,通過實例訪問的就是實例屬性了
實例方法是指定義在類中的方法, 它可以訪問和操作對象的實例屬性, 并且在調用時會自動傳入對象自身(通常用 self
來表示)作為第一個參數.
實例方法是與類的實例(對象)關聯的, 并且可以訪問和修改對象的狀態.
使用實例方法時, 需要先創建類的實例(對象), 然后通過對象調用方法, 在調用實例方法時, 不需要手動傳入 self
參數, Python會自動將對象本身傳遞給方法.
關于self
在實例方法中, 第一個參數通常是 self, 表示對象自身.
定義實例方法時, 必須將 self 作為方法的第一個參數.通過 self, 方法可以訪問對象的屬性和其他方法.- 在創建類的實例(對象)時, Python會自動傳遞 self 參數給實例方法, 不需要手動傳入.當調用對象的方法時, 無需顯式傳遞 self, Python會自動將對象本身傳遞給方法.
- 在實例方法內部, 可以通過 self 來訪問對象的屬性和方法.例如,
self.attribute
可以訪問對象的屬性,self.method()
可以調用對象的其他方法
4. 對象的初始化
__init__
是Python中一個特殊的方法, 用于初始化對象的屬性.它是在創建對象時自動調用的構造方法, 也叫做魔法方法.
在類的定義中, __init__
方法用于初始化對象的屬性.通常, 在創建對象時需要對對象的屬性進行初始化操作, 比如設置默認值或接收外部傳入的參數.
__init__
方法的命名是固定的, 必須使用雙下劃線 __
前綴和后綴.在調用類創建對象時, Python會自動調用類的 __init__
方法來初始化對象的屬性.
注意: __init__
方法只能返回None, 不能有其他返回值.
實例屬性
實例屬性是指定義在類的實例(對象)中的屬性, 每個對象都有自己獨立的實例屬性.實例屬性用于存儲對象的狀態和數據, 并且在類的實例化過程中被賦予特定的值.
在Python中, 實例屬性通常是在類的構造方法 __init__
中使用 self
關鍵字定義的.(類的實例屬性在類外(或者說是__init__方法外定義的實例屬性)也有定義的情況)
每個實例屬性都是一個對象獨有的變量, 不同的對象之間互不干擾.
class Student:def __init__(self, name, age):self.name = nameself.age = agedef introduce(self):print(f"大家好, 我的名字叫{self.name}, 今年{self.age}歲")self.study_course('英語')def study_course(self, course):print(f"{self.name}正在努力學習{course}")stu1 = Student("李四", 18)
stu1.introduce()
stu1.study_course("english")stu2 = Student("張三", 20)
stu2.introduce()
stu2.study_course("maths")
實例屬性和類屬性總結
-
定義位置:
- 實例屬性:實例屬性是定義在類的方法中(通常是在構造函數
__init__
中)通過self
關鍵字定義的,每個實例(對象)都有自己的一份實例屬性.
類屬性:類屬性是定義在類的方法之外的屬性, 直接在類的內部定義的, 屬于整個類, 所有實例共享同一份類屬性.
- 實例屬性:實例屬性是定義在類的方法中(通常是在構造函數
-
存儲位置:
-
實例屬性:每個實例(對象)都有自己獨立的實例屬性, 存儲在對象中.
-
類屬性:類屬性屬于整個類, 存儲在類中.
-
-
值的獨立性:
- 實例屬性:不同實例的同名實例屬性是相互獨立的, 一個實例的實例屬性修改不會影響其他實例.
- 類屬性:所有實例共享同一份類屬性, 但是通過一個實例修改類屬性時, 這個修改不會影響其他實例的類屬性.類屬性是屬于類的, 而不是屬于實例的, 因此每個實例都擁有獨立的類屬性副本, 互不影響.
-
訪問方式:
-
實例屬性:通過對象訪問, 使用表達式
對象名.屬性名
. -
類屬性:可以通過類名訪問, 也可以通過對象訪問.使用表達式
類名.屬性名
或對象名.屬性名
.
-
5. __str__
__str__
是Python中的特殊方法(魔法方法), 用于定義類的實例對象的字符串表示.
當我們使用print函數或str()函數打印一個類的實例對象時, 實際上是調用了該對象的__str__方法來獲取其字符串表示.
如果在類中定義了__str__
方法, 那么當我們打印該類的實例時, 會輸出__str__
方法返回的字符串.這對于自定義類的字符串表示非常有用, 可以讓我們以更加直觀和可讀的方式展示對象的內容.
主要用途包括:
- 打印:當你使用
print
函數打印一個對象時, 實際上是調用該對象的__str__
方法來獲取其字符串表示, 從而以更直觀和易讀的方式顯示對象的信息. - 字符串轉換:當你使用
str()
函數來將一個對象轉換為字符串時, 同樣會調用該對象的__str__
方法, 以獲得其字符串表示. - 字符串格式化:在字符串格式化時, 如果包含了對象, Python會自動調用對象的
__str__
方法, 以便獲取對象的字符串表示.
class Student:# 類屬性gender = '男'def __init__(self, name, age):# 實例屬性self.name = nameself.age = agedef introduce(self):print(f"大家好, 我的名字叫{self.name}, 今年{self.age}歲")self.study_course()def study_course(self, course="英語"):print(f"我正在努力學習{course}")def __str__(self):return f"學生: {self.name}, {self.age}, {self.gender}"# 1. 打印
stu = Student("李四", 18)
print(stu)
# 2. 字符串轉換
stu_string1 = str(stu)
print(stu_string1)
# 3. 字符串格式化
stu_string2 = f'{stu}'
print(stu_string2)# 輸出結果:
學生: 李四, 18, 男
學生: 李四, 18, 男
學生: 李四, 18, 男
6. 類之間的關系
繼承關系
真實世界中,類型之間 可能存在 范圍 包含關系.
比如:人 這個類型 和 亞洲人 這個類型.
人 是包括了 亞洲人 的。 如果 某人 是一個 亞洲人,那么它必定是一個 人.
這種關系,編程語言中稱之為 繼承關系.
比如上面的例子, 亞洲人 這個類 就 繼承 了 人 這個類.
通常我們把被繼承的類稱之為 父類 或者叫 基類.
把繼承類稱之為 子類 或者 派生類.
同樣的,以車為例, 上面我們定義了奔馳車 這個類, 我們還可以定義兩個 子類: 奔馳2016 和 奔馳2018 對應兩種不同款的奔馳車.
如下所示:
class BenzCar: brand = '奔馳' country = '德國' @staticmethoddef pressHorn(): print('嘟嘟~~~~~~')def __init__(self,color,engineSN):self.color = color # 顏色self.engineSN = engineSN # 發動機編號def changeColor(self,newColor):self.color = newColorclass Benz2016(BenzCar):price = 580000model = 'Benz2016' class Benz2018(BenzCar):price = 880000model = 'Benz2018'
大家可以發現定義子類的時候,必須指定它的父類是什么.
指定的方法就是在類名的后面的括號里寫上父類的名字.
大家注意: 子類會自動擁有父類的一切屬性和方法
為什么? 因為一個子類的實例對象 ,必定也是一個父類的實例對象. 當然需要擁有父類的一切屬性和方法.
就像 一個亞洲人 當然 擁有一個 人 所應該具有的一切特性.
比如,執行下面的代碼:
car1 = Benz2016('red','234234545622')
car2 = Benz2018('blue','111135545988') print (car1.brand)
print (car1.country)
car1.changeColor('black')print (car2.brand)
print (car2.country)
car2.pressHorn()
輸出結果如下:
奔馳
德國
奔馳
德國
嘟嘟~~~~~~
一個子類在繼承父類的一切特性的基礎上,可以有自己的屬性和方法.
比如:
class Benz2018(BenzCar):price = 880000model = 'Benz2018' def __init__(self,color,engineSN,weight):# 先調用父類的初始化方法BenzCar.__init__(self,color,engineSN)self.weight = weight # 車的重量self.oilweight = 0 # 油的重量# 加油def fillOil(self, oilAdded):self.oilweight += oilAdded self.weight += oilAdded
這里 子類 Benz2018 ,新增了兩個 類屬性
價格: price
型號: model
新增了兩個實例屬性
整車重量:weight
油的重量:oilweight
新增了一個實例方法 fillOil , 對應 加油這個行為.
這個行為會導致 實例屬性 weight 和 oilweight 變化,所以必須是 實例方法.
這樣定義好了以后, 就可以創建該類的實例,并訪問其新的方法和屬性了.
car2 = Benz2018('blue','111135545988',1500)
print (car2.oilweight)
print (car2.weight)
car2.fillOil(50)
print (car2.oilweight)
print (car2.weight)
要特別注意的是, 子類的初始化方法里面,如果有一部分的初始化代碼和父類的初始化相同(通常都是這樣),需要顯式的 調用父類的初始化方法 __init__
而且要傳入相應的參數, 像上面那樣,然后可以加上自己的特有的初始化代碼. 如下所示:
def __init__(self,color,engineSN,weight):# 先調用父類的初始化方法BenzCar.__init__(self,color,engineSN)self.weight = weight self.oilweight = 0
如果子類 沒有 自己的初始化方法,實例化子類對象時,解釋器會自動調用父類初始化方法,如下:
class Rect:def __init__(self):print('初始化 rect')class Squre(Rect):passs = Squre()
運行結果,會打印出 ‘初始化 rect’
但是,如果子類 有自己 的初始化方法,實例化子類對象時,解釋器就不會自動化調用父類的初始化方法,如下
class Rect:def __init__(self):print('初始化 rect')class Square(Rect):def __init__(self):print('初始化 square')s = Squre()
運行結果只會打印 初始化 square.
調用父類的方法,除了直接用父類的名字 BenzCar, 還可以使用 函數 super()
像這樣:
def __init__(self,color,engineSN,weight):# 同樣是調用父類的初始化方法super().__init__(color, engineSN)self.weight = weight self.oilweight = 0
這樣使用的時候,方法參數中 不需要加上 self 參數.
使用 super 的好處之一就是:子類中調用父類的方法,不需要 顯式指定 父類的名字. 代碼的可維護性更好.
想象一下,如果 BenzCar 有很多子類,如果哪一天 BenzCar 類改了名字,采用 super 這樣的寫法,就不需要修改子類的代碼了.
注意 super不僅僅可以調用父類的初始化方法,也可以調用父類的其他方法.
一個子類,同時還可以是另一個類的父類,
比如 亞洲人 可以是 人 的子類, 同時可以是 中國人 的父類.
因為一個中國人,一定是一個亞洲人, 當然也一定是一個 人.
同樣的,上面的車的例子, 我們還可以定義 奔馳2018混合動力 作為 奔馳2018 的 子類.
定義的語法還是一樣的:
class Benz2018Hybrid(Benz2018):model = 'Benz2018Hybrid' price = 980000def __init__(self,color,engineSN,weight):Benz2018.__init__(self,color,engineSN,weight)
同樣,類 Benz2018Hybrid 也會擁有其父類 Benz2018 的一切屬性和方法,自然也包括 父類的父類 BenzCar 的一切屬性和方法
car2 = Benz2018Hybrid('blue','111135545988',1500)
print (car2.oilweight)
print (car2.weight)
car2.fillOil(50)
print (car2.oilweight)
print (car2.weight)
組合關系
除了上面的繼承關系, 類之間還有一種常見的組合關系.
所謂組合關系,就是一個類實例的屬性里面包含另外一個類實例.
比如:
class BenzCar: brand = '奔馳' country = '德國' def __init__(self,color,engineSN):self.color = color # 顏色self.engineSN = engineSN # 發動機編號
這樣的定義,類 BenzCar 中
brand 屬性就是一個字符串對象 奔馳
country 屬性就是一個字符串對象 德國
而該類的實例對象中,就包含了 兩個屬性 color 和 engineSN, 都是字符串對象
我們可以說 該類由 一些字符串對象 組合 而成.
甚至還可以包含 我們自己定義的類的實例,比如:
# 輪胎
class Tire: def __init__(self,size,createDate):self.size = size # 尺寸self.createDate = createDate # 出廠日期class BenzCar: brand = '奔馳' country = '德國' def __init__(self,color,engineSN,tires):self.color = color # 顏色self.engineSN = engineSN # 發動機編號self.tires = tires# 創建4個輪胎實例對象
tires = [Tire(20,'20160808') for i in range(4)]
car = BenzCar('red','234342342342566',tires)
上面的例子里,奔馳汽車對象就 包含 了4個輪胎 Tire 對象.
我們可以說奔馳汽車對象是由 4個輪胎對象 組合 而成,形成了對象的組合關系.
對象的 屬性 變量 保存了 組合它的那些對象.
組合關系,可以通過上層對象的屬性一步的訪問到內部對象的屬性
比如,我們可以通過 BenzCar 對象 訪問其內部的輪胎對象
print(car.tires[0].size)
Python解釋器對這個表達式 car.tires[0].size 是從左到右依次執行的,如下所示:
car.tires # BenzCar實例的tires屬性,得到一個列表,里面是四個 Tire 實例對象car.tires[0] # 得到BenzCar實例的tires屬性列表里面的第1個Tire 實例對象car.tires[0].size # 得到BenzCar實例的tires屬性列表里面的第1個Tire 實例對象的size屬性
7. 補充練習
"""
創建一個簡單的學生管理系統,包含以下功能:定義一個Student類,包含以下屬性:學號(number),姓名(name),年齡(age),性別(gender)和成績(score)。實現類的初始化方法__init__,用于初始化學生的屬性。實現類的__str__方法,用于返回學生信息的字符串表示,格式為:學號:[學號],姓名:[姓名],年齡:[年齡],性別:[性別],成績:[成績]。定義一個學生管理類StudentManager,用于管理學生信息。該類應該包含以下功能:添加學生:能夠添加一個學生的信息到學生列表中。
顯示所有學生:能夠打印出所有學生的信息。
因為之前我們已經做過了類似的管理系統, 所以這里就不再做很復雜的功能, 只做兩個小功能達到練習的目的即可.
"""# 學生類
class Student:def __init__(self, number, name, age, gender, score):self.number = numberself.name = nameself.age = ageself.gender = genderself.score = scoredef __str__(self):return f"學號:[{self.number}],姓名:[{self.name}],年齡:[{self.age}],性別:[{self.gender}],成績:[{self.score}]"# 學生管理類
class StudentManager:def __init__(self):self.stu_list = []def add_stu(self, student):self.stu_list.append(student)print(f'添加學生{student.name}成功')def show_all_stu(self):for stu in self.stu_list:print(stu)def main():# 主流程student_manager = StudentManager()print('歡迎進入學生管理系統')while True:print('1: 添加學生')print('2: 展示所有學生')print('0: 退出系統')choice = int(input("請輸入操作編號: "))if choice == 1:number = input('請輸入學生學號')name = input('請輸入學生姓名')age = input('請輸入學生年齡')gender = input('請輸入學生性別')score = input('請輸入學生分數')student = Student(number, name, age, gender, score)student_manager.add_stu(student)elif choice == 2:student_manager.show_all_stu()elif choice == 0:print(f"退出學生管理系統")breakelse:print('您輸入的指令是無效指令')if __name__ == '__main__':main()
|
|