第九章、物件導向
第九章、物件導向
一、類的定義
-
格式:
-
# classnam類名 class classname(object): """ 程式碼段 """ pass
-
-
呼叫方式:例項化
-
class Student(): name = "" age = 0 def print_file(): pass # 例項化 student = Student() # 呼叫類下面的方法 student.print_file() # 執行會報錯 # 解決方法 在方法中間寫入self class Student(): name = "" age = 0 def print_file(self): print("name:"+name) print("age:"+str(age)) student = Student() student.print_file() # 執行結果 還是報錯 繼續修改 class Student(): name = "" age = 0 def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student = Student() student.print_file() # 執行結果 name: age:0
-
類的最基本的作用就是封裝程式碼
-
類中的方法在書寫時引數一定要加
self
-
二、類與物件
-
在別的模組中引用類
-
from c1 import Student student = Student() student.print_file() # 結果: name: age:0
-
-
方法和函式的區別
- 沒有一個絕對的區別
-
定義在類中的變數不能叫變數,應該是資料成員,定義在類外面的資料才叫變數
-
類:
- 什麼是類?
- 類就是將資料和對這些資料的操作封裝在了一起
- 類是一個事物的抽象,並不是具體的
- 資料成員刻畫特徵
- 方法刻畫行為,行為需要找對主體
- 類就像一個模板一樣,通過類可以產生很多個物件
- 什麼是類?
-
物件:
- 什麼是物件
- 物件則是表示一個具體的事物,就是將類例項化
- 當類被例項化之後就會變成例項物件
- 只有給例項化後的類傳入特徵值,物件才能有對應特徵
- 什麼是物件
-
例項化:
-
class Student(): name = "" age = 0 def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student() student2 = Student() student3 = Student() # 建立3個不同的例項化物件,特徵是相同的,但是實際上又是獨立開的不同的物件
-
三、建構函式
-
如果要在類中傳入特徵值,需要定義一個特殊的函式
__init__()
-
class Student(): name = "" age = 0 def __init__(self): # 建構函式 print("student") pass def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student() student1.__init__() # 結果: student student # 出現了兩次列印
-
出現兩次的原因是因為當我們例項化類的話,建構函式會被自動呼叫,也可以主動呼叫建構函式
-
建構函式返回值是None,不能返回別的值
-
建構函式的作用
-
可以讓模板生成不同的物件
-
在建構函式中建立了形參後,就必須在例項化類中寫入實參,不寫的話會報錯
class Student(): # name = "" # age = 0 def __init__(self,name,age): # 建構函式 print("student") pass def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student() student1.__init__() # 執行結果: 報錯 class Student(): # name = "" # age = 0 def __init__(self,name,age): # 建構函式 print("student") pass def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student('劉小剛', 2) student1.print_file() # 執行結果: student 空 # 並沒有修改成功 class Student(): name = "" age = 0 def __init__(self,name,age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age print("student") pass def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student('劉小剛', 2) student1.print_file() # 執行結果: student name:劉小剛 age:2
-
四、類變數1和例項變數2
-
類變數:是定義在類中的變數
-
class Student(): # 類變數 name = "" age = 0 def __init__(self,name,age): # 建構函式 # 初始化物件的特徵 # 例項變數 self.name = name self.age = age print("student")
-
類變數的意義:類變數和特徵變數是無關的,也就是和成員屬性是無關的
-
-
例項變數:是定義在
__init__()
中,例項變數的定義方式是self.變數名
-
class Student(): # 類變數 name = "" age = 0 def __init__(self,name,age): # 例項變數 self.name = name self.age = age print("student")
-
-
例項變數和類變數的區別
-
class Student(): name = "qiyue" age = 0 def __init__(self,name,age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age student1 = Student('劉小剛', 2) print(student1.name) print(Student.name) # 結果: 劉小剛 qiyue
-
物件的.name和例項物件的.name是不同的
-
-
__dict__
3-
class Student(): name = "qiyue" age = 0 def __init__(self,name,age): # 建構函式 # 初始化物件的特徵 name = name age = age def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student('劉小剛', 2) print(student1.name) # 結果: qiyue
-
為何沒有修改該變數
-
class Student(): name = "qiyue" age = 0 def __init__(self,name,age): # 建構函式 # 初始化物件的特徵 self.name = name age = age def print_file(self): print("name:"+self.name) print("age:"+str(self.age)) student1 = Student('劉小剛', 2) print(student1.__dict__) # 結果 只有一個例項變數,{'name': '劉小剛'}
-
為什麼例項變數不存在,還能列印出qiyue
- 這和變數的尋找機制有關,當在特徵變數中找不到值的時候,他就會到類中尋找,若在類中也找不到,那麼就會向上(父類)中繼續尋找
-
-
self
- 特性:如果要在類中定義一個例項方法,那麼第一個引數需要寫self,而在我們呼叫這個方法發時候是不需要傳入這個引數的,self是預設傳入的
- self可以不叫self,可以寫this或別的,但是python建議我們用self,顯勝與隱
- self的意義:呼叫這個方法的例項物件,換句話說就是self代表的是呼叫的物件,而不是類
-
例項方法:
-
是和物件相關聯的方法
-
例項方法中訪問類變數
-
在例項方法中無法訪問類變數。
-
class Student(): name1 = "qiyue" age1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age print(name1) print(age1) student1 = Student('劉小剛', 2) # 結果 報錯
-
-
通過類名直接呼叫類變數、或者通過
self.__class__.類變數名
-
class Student(): name1 = "qiyue" age1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age # print(Student.name1) print(self.__class__.name1) # print(Student.age1) print(self.__class__.age1) student1 = Student('劉小剛', 2) # 結果 qiyue 0
-
-
五、類方法
-
為什麼會有類方法
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 student1 = Student('劉小剛', 2) student2 = Student('剛小劉', 2) student3 = Student('小劉剛', 2) print(Student.sum1) # 結果: 3
-
每建立一個物件,類變數都會自動加一
-
-
類方法定義:
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 def print_file(self): # 例項方法 print("name:"+self.name) print("age:"+str(self.age)) @classmethod def plus_sum(cls): # 類方法 pass
-
@classmethod
:@
是裝飾器的定義 -
cls
:是預設引數,可以更改,代表的是類 -
用來操作和類相關的變數
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 def print_file(self): # 例項方法 print("name:"+self.name) print("age:"+str(self.age)) @classmethod def plus_sum(cls): # 類方法 cls.sum1 += 1 print(cls.sum1) student1 = Student('劉小剛', 2) Student.plus_sum() student2 = Student('剛小劉', 2) Student.plus_sum() student3 = Student('小劉剛', 2) Student.plus_sum() print(Student.sum1) # 結果: 2 4 6 6
-
類方法時可以用物件直接呼叫的
-
可以看出類並沒有例項化,可以通過類直接呼叫類函式。
當然類方法,例項也可以呼叫,但是並沒有什麼用,違反了初衷:類方法就是專門供類使用
-
-
六、靜態方法
-
靜態方法的定義
-
沒有強制傳入引數、就是一個普普通通的方法
-
class Student(): @staticmethod def add(x,y): # 靜態方法 print("This is a static method") student1 = Student('劉小剛', 2) # 結果 無
-
物件和類都可以呼叫這個方法
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 def print_file(self): # 例項方法 print("name:"+self.name) print("age:"+str(self.age)) @classmethod def plus_sum(cls): # 類方法 cls.sum1 += 1 print(cls.sum1) pass @staticmethod def add(x,y): print("This is a static method") student1 = Student('劉小剛', 2) student1.add(1,1) Student.add(1,3) # 結果: This is a static method This is a static method
-
靜態方法內部也可以呼叫類變數
-
靜態方法和類關聯非常弱,可以用在和類沒有太大關係的時候用
-
七、成員4可見性:公開5和私有6
-
類的內外之分
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 def print_file(self): # 例項方法 print("name:"+self.name) print("age:"+str(self.age)) self.do_homework() def do_homework(slef): # 例項方法 pass student1 = Student('劉小剛', 2)
-
-
使用例項方法對例項變數的值進行修改
-
通過物件操作例項變數是不安全的,可以通過方法來操作例項變數會更加安全,因為可以對例項變數進行限制
-
class Student(): name1 = "qiyue" age1 = 0 sum1 = 0 def __init__(self, name, age): # 建構函式 # 初始化物件的特徵 self.name = name self.age = age Student.sum1 += 1 def print_file(self): # 例項方法 print("name:"+self.name) print("age:"+str(self.age)) self.do_homework() def marking(self,score): # 例項方法 if score < 0: return "不能夠打負分" self.score = score print(self.name + "同學本次成績為:"+str(self.score)) student1 = Student('劉小剛', 2) student1.marking(59) # 結果: 劉小剛同學本次成績為:59 result = student1.marking(-1) print(result) # 結果: 不能夠打負分
-
-
變數私有化:
-
__
:雙下劃線對變數和方法進行私有化 -
建構函式是特有函式,所以可以訪問
-
class Student(): # 類變數 sum1 = 0 # 成員屬性 def __init__(self): self.__name = "劉小剛" self.__age = "10" def __marking(self): # 私有方法 print("劉小剛很厲害,張小方很菜") student1 = Student() student1.__marking() # 執行結果: AttributeError: 'Student' object has no attribute '__marking' 私有方法無法呼叫
-
# 為什麼私有成員屬性不光可以訪問,而且還能改變值 class Student(): # 類變數 sum1 = 0 # 成員屬性 def __init__(self): self.__name = "劉小剛" self.__age = "10" def __marking(self): print("劉小剛很厲害,張小方很菜") pass student1 = Student() # student1.__marking() student1.__name = "張小方" print(student1.__name) # 結果: 張小方
-
注意:之所以可以訪問是因為,
.__變數名
是新建成員變數,原來的變數是無法進行訪問的,因為名字已經被修改了,不能通過動態方式建立私有變數 -
class Student(): # 類變數 sum1 = 0 # 成員屬性 def __init__(self): self.__name = "劉小剛" self.__age = "10" def __marking(self): print("劉小剛很厲害,張小方很菜") pass student1 = Student() student1.__name = "張小方" print(student1.__dict__) # 結果: {'_Student__name': '劉小剛', '_Student__age': '10', '__name': '張小方'}
-
class Student(): # 類變數 sum1 = 0 # 成員屬性 def __init__(self): self.__name = "劉小剛" self.__age = "10" def __marking(self): print("劉小剛很厲害,張小方很菜") pass student1 = Student() print(student1._Student__age) # 結果: 10
-
八、繼承
-
一個程式碼塊中最好只定義一個類
-
# c5.py # 父類 class people(): pass # c6.py from c5 import people # 繼承 class Student(people): # 類變數 sum1 = 0 # 成員屬性 def __init__(self): self.__name = "劉小剛" self.__age = "10" def __marking(self): print("劉小剛很厲害,張小方很菜") pass student1 = Student()
-
建立物件呼叫
-
# c5.py class Human(): # 類變數 sum1 = 0 # 成員屬性 def __init__(self, name, age): self.name = name self.age = age # 類方法 def get_name(self): print(self.name) # c6.py from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 pass student1 = Student("劉小剛","10") print(student1.sum1) print(student1.name) print(student1.age) # 執行結果: 0 劉小剛 10 # 子類繼承父類的變數
-
-
一個父類有多個子類,子類的下面也能有子子類,深度不限(單繼承)
-
from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 def __init__(self,school,name,age): self.school = school Human.__init__(self,name,age) student1 = Student("七彩幼兒園","劉小剛","10") print(student1.school) print(student1.name) print(student1.age) # 執行結果: 七彩幼兒園 劉小剛 10
-
為什麼需要在
__init__()
中傳入self
:因為在例項化物件的時候,python自動幫忙將self傳入進去,而是用類名.例項方法 的這種操作就相當於是在呼叫例項方法,就是當成函式來呼叫,你們就要傳入引數 -
from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 def __init__(self,school,name,age): self.school = school Human.__init__(self,name,age) def do_homework(self): print("do_homework") student1 = Student("七彩幼兒園","劉小剛","10") # 等價 student1.do_homework() Student.do_homework(student1) # 結果: do_homework do_homework
-
正要呼叫的缺點:當父類方法多次被呼叫時,需要多次更改父類名字
-
第二種呼叫父類方法的方式
super
,相當於代表父類這個關鍵字-
from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 def __init__(self,school,name,age): self.school = school # Human.__init__(self,name,age) super(Student,self).__init__(name,age) def do_homework(self): print("do_homework") student1 = Student("七彩幼兒園","劉小剛","10") student1.do_homework() # 結果: do_homework
-
super(父類名,self)
:也可以呼叫父類中重名的方法 -
from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 def __init__(self,school,name,age): self.school = school # Human.__init__(self,name,age) super(Student,self).__init__(name,age) def do_homework(self): super(Student,self).do_homework() print("do_homework") student1 = Student("七彩幼兒園","劉小剛","10") student1.do_homework() # 結果: do_english_homework do_homework
-
-
super(父類名,self)
:也可以呼叫父類中重名的方法 -
from c5 import Human # 類、物件 class Student(Human): # 類變數 # 成員屬性 def __init__(self,school,name,age): self.school = school # Human.__init__(self,name,age) super(Student,self).__init__(name,age) def do_homework(self): super(Student,self).do_homework() print("do_homework") student1 = Student("七彩幼兒園","劉小剛","10") student1.do_homework() # 結果: do_english_homework do_homework
相關文章
- 物件導向-物件導向思想物件
- 物件導向與程式導向物件
- 程式導向與物件導向物件
- “程序導向”和“物件導向”物件
- 物件導向物件
- 物件導向,搞定物件物件
- JAVA物件導向基礎--物件導向介紹Java物件
- PHP 物件導向 (九)物件導向三大特徵PHP物件特徵
- PHP物件導向PHP物件
- 物件導向 -- 反射物件反射
- JavaScript 物件導向JavaScript物件
- JS物件導向JS物件
- Java物件導向Java物件
- Python——物件導向Python物件
- 物件導向--下物件
- scala物件導向物件
- 物件導向(下)物件
- Python物件導向Python物件
- 物件導向(oop)物件OOP
- [Java物件導向]Java物件
- python 物件導向Python物件
- Java — 物件導向Java物件
- 物件導向(上)物件
- python-程式導向、物件導向、類Python物件
- Java物件導向——類與物件Java物件
- Js物件導向(1): 理解物件JS物件
- php中的程式導向與物件導向PHP物件
- 初識物件導向物件
- 物件導向拾遺物件
- 物件導向--繼承物件繼承
- java物件導向(上)Java物件
- java物件導向(中)Java物件
- python物件導向(一)Python物件
- 物件導向css oocss物件CSS
- PHP物件導向(三)PHP物件
- golang 物件導向特性Golang物件
- 物件導向相關物件
- 物件導向:繼承物件繼承