面向对象and类
類和對象:
1.什么叫類:類是一種數據結構,就好比一個模型,該模型用來表述一類事物(事物即數據和動作的結合體),用它來生產真實的物體(實例)。
2.什么叫對象:睜開眼,你看到的一切的事物都是一個個的對象,你可以把對象理解為一個具體的事物(事物即數據和動作的結合體)
? ? (鉛筆是對象,人是對象,房子是對象,狗是對象,alex是對象,配齊是對象,元昊是對象)
3.類與對象的關系:對象都是由類產生的,上帝造人,上帝首先有一個造人的模板,這個模板即人的類,然后上帝根據類的定義來生產一個個的人
4.什么叫實例化:由類生產對象的過程叫實例化,類實例化的結果就是一個對象,或者叫做一個實例(實例=對象)
三大編程范式:
編程范式即編程的方法論,標識一種編程風格
三大編程范式:
1.面向過程編程:捂襠派
2.函數式編程:峨美眉妹妹派
3.面向對象編程:少林蛋黃派
面向對象編程與面向對象設計
面向對象設計(Object oriented design):將一類具體事物的數據和動作整合到一起,即面向對象設計
1 #用基于結構化的語言來實現面向對象設計2 def wang(name,genle,type):3 def jiao(dog):4 print("%s正在叫"%dog["name"])5 def chi(dog):6 print("%s正在吃"%dog["name"])7 def init(name,genle,type):8 dog1 ={9 "name":name, 10 "genle":genle, 11 "type":type, 12 "jiaoa":jiao, 13 "chi":chi 14 } 15 return dog1 16 return init(name,genle,type) 17 18 d1 = wang("yuanhao","gong","tianyuanquan") 19 print(d1) 20 d1["jiaoa"](d1)面向對象編程(object-oriented programming):用定義類+實例/對象的方式去實現面向對象的設計
1 class Chinese:2 name = "abc"3 def chifan(self,x):4 print("姓名:%s喜歡吃%s"%(self.mingzi,x))5 def shuijiao(self):6 print("nianling:%s"%self.nianling)7 def __init__(self,name,age):8 self.mingzi = name9 self.nianling = age 10 f1 = Chinese("alex",18) 11 f1.chifan("eat") 12 f1.shuijiao()類的聲明
1 大前提:2 1.只有在python2中才分新式類和經典類,python3中統一都是新式類3 2.新式類和經典類聲明的最大不同在于,所有新式類必須繼承至少一個父類4 3.所有類甭管是否顯式聲明父類,都有一個默認繼承object父類(講繼承時會講,先記住)5 在python2中的區分6 經典類:7 class 類名:8 pass9 10 經典類: 11 class 類名(父類): 12 pass 13 14 在python3中,上述兩種定義方式全都是新式類 python3中聲明類:1 1 '''2 2 class 類名:3 3 '類的文檔字符串'4 4 類體5 5 '''6 6 7 7 #我們創建一個類8 8 class Data:9 9 pass 10 10 11 11 #用類Data實例化出一個對象d1 12 12 d1=Data()
類的屬性
類有數據屬性跟函數屬性(又稱方法屬性)
1 class Chinese:2 name = "abc"3 def chifan(self,x):4 print("姓名:%s喜歡吃%s"%(self.mingzi,x))5 def shuijiao(self):6 print("nianling:%s"%self.nianling)7 def __init__(self,name,age):#為實例定制數據屬性,可以使用類的一個內置方法__init__()該方法,在類()實例化是會自動執行8 self.mingzi = name9 self.nianling = age 10 f1 = Chinese("alex",18) #類的實例化,相當于運行__init__函數,將參數傳給__init函數體中對應的位置,生成一個字典,其中self即代表f1自身 11 f1.chifan("eat")#通過.調用類的屬性,首先會在__init__作用域內查找,若沒找到會到類的屬性中尋找,實例化生成的對象只具備數據屬性,調用的方法為類的屬性并非生成的對象所具備的屬性 12 f1.shuijiao()有兩種方法查看類的屬性
dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key為屬性名,value為屬性值
1 class Chinese: 2 name = "abc" 3 def chifan(self): 4 print(123) 5 def shuijiao(self): 6 print("456") 7 print(Chinese.name)#打印的是name屬性對應的內容 8 print(Chinese.__dict__)#顯示結果是一個字典,包含類的所有屬性:屬性值 9 print(dir(Chinese))#顯示結果是一個列表,包含類(包含內建屬性在內的)所有的屬性名?特殊的類屬性
__name__,類的名字
__doc__,查看類的文檔字符串
?__module__,類定義所在的模塊__class__,實例C對應的類(僅新式類中)?
類的方法屬性增刪改查:
1 class math:2 country = "China"3 def chi(self,food):4 print("%s正在吃%s"%(self.mingzi,food))5 def __init__(self,name):6 self.mingzi = name7 f1 = math("alex")8 print(math.country) #查看9 # print(dir(math)) 10 # print(math.__dict__) 11 def yundong(self,hobby):#增加 12 print("%s正在%s"%(self.mingzi,hobby)) 13 math.aihao = yundong 14 #print(math.__dict__) 15 f1.aihao("打籃球") 16 #del math.chi 17 #print(math.__dict__) 18 def aichi(self,food):#修改 19 print("%s很開心的吃%s"%(self.mingzi,food)) 20 math.chi =aichi 21 f1.chi("面")類的數據屬性增刪改查:
1 class math:2 country = "China"3 def chi(self,food):4 print("%s正在吃%s"%(self.mingzi,food))5 def __init__(self,name,age):6 self.mingzi = name7 self.nianling = age8 9 f1 = math("alex",18) 10 print(f1.__dict__) #查看 11 f1.mingzi = "eric" #修改 12 print(f1.__dict__) 13 f1.xingbie = "男" # 增加 14 del f1.mingzi #刪除 15 print(f1.__dict__)類屬性與對象(實例)屬性
1.實例化會自動觸發init函數的運行,最后返回一個值即實例,我們要找的實例屬性就存放在init函數的局部作用域里
2.類有類的屬性字典,就是類的作用域,實例有實例的屬性字典,即實例的作用域
3.綜上,一個點代表一層作用域,obj.x先從自己的作用域找,自己找不到去外層的類的字典中找,都找不到,就會報錯
4.在類中沒有使用點的調用,代表調用全局變量
1 country = "China" 2 class Chinese: 3 country = "japan" 4 def __init__(self,name): 5 self.mingzi = name 6 print(country)#打印的是普通變量country,非類結構中的變量,要調用類中的變量要用"."調用 7 f1 = Chinese("alex")靜態屬性,類方法,靜態方法
1 class Room:2 arg = 1233 def __init__(self,name,weith,lenth,height):4 self.mingzi = name5 self.kuandu = weith6 self.changdu = lenth7 self.gaodu = height8 @property#靜態屬性,將實例化對象變成類的數據屬性,將該方法封裝起來,作用可隱藏邏輯代碼,直接用實例+"."調用該方法9 def tiji(self): 10 return self.kuandu*self.changdu*self.gaodu 11 12 @classmethod#類方法,專門供類使用,與實例無關,類方法只能訪問類相關的屬性,不能訪問實例屬性,與實例無關 13 def tell_info(cls,x):#默認參數cls不可變,為類名,后邊可接參數 14 print(cls) 15 print("------>",Room.arg,x) 16 17 @staticmethod #靜態方法 ,類的靜態方法,沒有默認參數,不能使用類變量和實例變量 18 def op(x,y,z): 19 print(x,y,z) 20 f1 = Room("alex",10,50,20) 21 print(f1.tiji)#由于用了property方法封裝該方法(已變成數據屬性),故可直接調用該數據屬性 22 Room.tell_info("abc") 23 Room.op(1,2,3) #類傳參數可以調用 24 f1.op(1,2,3) #實例傳參數可以調用組合:做關聯
1 class School:2 def __init__(self,name,difang):3 self.name = name4 self.difang = difang5 class Teacher:6 def __init__(self,name,sex,school):7 self.name = name8 self.sex = sex9 self.school = school 10 class Lesson: 11 def __init__(self,name,price,period,techer): 12 self.name = name 13 self.price = price 14 self.period = period 15 self.techer = techer 16 17 p1 = School("old boy","北京") 18 t1 = Teacher("alex","male",p1)#將p1對象直接添加到t1對象屬性中 19 L1 = Lesson("python班",10000,"4month",t1) 1 class School:2 def __init__(self,name,difang):3 self.name = name4 self.difang = difang5 class Teacher:6 def __init__(self,name,sex,school):7 self.name = name8 self.sex = sex9 self.school = school 10 class Lesson: 11 def __init__(self,name,price,period,techer): 12 self.name = name 13 self.price = price 14 self.period = period 15 self.techer = techer 16 17 p1 = School("old boy","北京") 18 t1 = Teacher("alex","male",p1)#將p1對象直接添加到t1對象屬性中 19 L1 = Lesson("python班",10000,"4month",t1)面向對象編程的三大特征:
類的繼承:類的繼承跟現實生活中的父、子、孫子、重孫子、繼承關系一樣,父類又稱為基類。
python中類的繼承分為:單繼承和多繼承
1 class ParentClass1:2 pass3 4 class ParentClass2:5 pass6 7 class SubClass(ParentClass1): #單繼承8 pass9 10 class SubClass(ParentClass1,ParentClass2): #多繼承 11 pass子類繼承了基類的所有屬性
1 class Dad:2 money = 103 def __init__(self,name):4 self.name = name5 def hit_son(self):6 print("打人")7 class Son(Dad):#繼承參數“類”的所有屬性8 money = 5000#當子級類屬性跟父級類屬性重名時,調用當級類方法會先從當級尋找,找不到會去父級找9 pass 10 p1 = Son("eric") 11 print(p1.name) 12 p1.hit_son() 13 print(p1.money)當類之間有顯著不同,并且較小的類是較大的類所需要的組件時,用組合比較好
當類之間有很多相同的功能,提取這些共同的功能做成基類,用繼承比較好
?繼承同時具有兩種含義:
?
含義一.繼承基類的方法,并且做出自己的改變或者擴展(代碼重用)
?
含義二.聲明某個子類兼容于某基類,定義一個接口類,子類繼承接口類,并且實現接口中定義的方法
1 接口繼承2 import abc #調用接口繼承模塊3 4 class All_file(metaclass=abc.ABCMeta):#聲明某個子類兼容于某基類,定義一個接口類,子類繼承接口類,并且實現接口中定義的方法5 @abc.abstractclassmethod #裝飾器使方法具備接口繼承特性6 def read(self):7 pass8 @abc.abstractclassmethod9 def write(self): 10 pass 11 12 class Disk(All_file):#子類繼承基類時,必須對基類的方法進行派生才可實例化 13 def read(self): 14 print("disk-read") 15 def write(self): 16 print("disk-write") 17 class Cd(All_file): 18 def read(self): 19 print("cd-read") 20 def write(self): 21 print("cd-write") 22 class Mem(All_file): 23 def read(self): 24 print("mem-read") 25 def write(self): 26 print("mem-write") 27 p1 = Disk() 28 p1.read(繼承順序:python如果繼承了多個類,遵循深度優先跟廣度優先順序
當類時經典類時,多繼承情況下,會按照深度優先方式查找
當類是新式類時,多繼承情況下,會按照廣度優先方式查找
經典類與新式類的差別:新式類在定義時便自動繼承了object類,而經典類沒有
新式類繼承順序:對于你定義的每一個類,python會計算出一個方法解析順序(MRO)列表,這個MRO列表就是一個簡單的所有基類的線性順序列表
為了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止。
而這個MRO列表的構造是通過一個C3線性化算法來實現的。我們不去深究這個算法的數學原理,它實際上就是合并所有父類的MRO列表并遵循如下三條準則:
1.子類會先于父類被檢查
2.多個父類會根據它們在列表中的順序被檢查
3.如果對下一個類存在兩個合法的選擇,選擇第一個父類
子類中調用父類方法
1 class jiaotong:2 def __init__(self,name,speed):3 self.name = name4 self.speed = speed5 def run(self):6 print("%srunning!"%self.name)7 class bicycle(jiaotong):8 def __init__(self,name,speed,type):9 #jiaotong.__init__(self,name,speed)#第一種方法:類調用,子級繼承父級,可以在調用父級方法的基礎上進行派生,減少重復代碼 10 super().__init__(name,speed)#第二種方法:用內置super().調用父級方法 11 self.type = type 12 def run(self): 13 jiaotong.run(self) 14 print("%s開動了"%self.name) 15 16 17 f1 = bicycle("danche",10,"meilida") 18 print(f1.name,f1.speed,f1.type) 19 f1.run()?
轉載于:https://www.cnblogs.com/jasonenbo/p/6211674.html
總結
- 上一篇: UCenter创始人密码正确但是登录不了
- 下一篇: InnoDB与MyISAM引擎区别