第一章 面向对象编程
面向?qū)ο笳Z(yǔ)法
attack_vals = {"京巴":30,"藏獒":80 } def dog(name,d_type): # 模板data ={"name":name,"d_type":d_type,# "attack_val":30,"life_val":100}if d_type in attack_vals:data["attack_val"] = attack_vals[d_type]else:data["attack_val"] = 15return datadef person(name,age):data = {"name":name,"age":age,"life_val":100}if age>18:data["attack_val"] =50else:data["attack_val"] =30return datadef dog_bite(dog_obj,person_obj):person_obj["life_val"] -= dog_obj["attack_val"] # 執(zhí)行咬人動(dòng)作print("狗[%s]咬了人[%s]一口,人掉血[%s],還有血量[%s]..."%(dog_obj['name'],person_obj['name'],dog_obj["attack_val"],person_obj["life_val"])) def beat(person_obj,dog_obj):dog_obj["life_val"] -= person_obj["attack_val"]print("人[%s]打了狗[%s]一棒,狗掉血[%s],還有血量[%s]..."%(person_obj["name"],dog_obj["name"],person_obj["attack_val"],dog_obj["life_val"])) d1 = dog("mjj","京巴") # 實(shí)體 d2 = dog("mjj2","藏獒") p1 = person("alex",22) dog_bite(d1,p1) beat(p1,d1) dog_bite(p1,d2) print(d1,d2) print(p1)人是不應(yīng)該調(diào)用狗的功能的,如何在代碼級(jí)別實(shí)現(xiàn)這個(gè)限制呢?
attack_vals = {"京巴":30,"藏獒":80 } def dog(name,d_type): # 模板data ={"name":name,"d_type":d_type,"life_val":100}if d_type in attack_vals:data["attack_val"] = attack_vals[d_type]else:data["attack_val"] = 15def dog_bite( person_obj):person_obj["life_val"] -= data["attack_val"] # 執(zhí)行咬人動(dòng)作print("狗[%s]咬了人[%s]一口,人掉血[%s],還有血量[%s]..." % (data['name'],person_obj['name'],data["attack_val"],person_obj["life_val"]))data["bite"] = dog_bite # 為了從函數(shù)外部可以調(diào)用這個(gè)dog_bite方法return datadef person(name,age):data = {"name":name,"age":age,"life_val":100}if age>18:data["attack_val"] =50else:data["attack_val"] =30def beat(dog_obj):dog_obj["life_val"] -= data["attack_val"]print("人[%s]打了狗[%s]一棒,狗掉血[%s],還有血量[%s]..." % (data["name"],dog_obj["name"],data["attack_val"],dog_obj["life_val"]))data["beat"] = beatreturn datad1 = dog("mjj","京巴") # 實(shí)體 d2 = dog("mjj2","藏獒") p1 = person("alex",22) d1["bite"](p1) # 咬人 d1["bite"](p1) # 咬人 d1["bite"](p1) # 咬人 p1["beat"](d1) # 打狗?編程范式
編程是 程序 員 用特定的語(yǔ)法+數(shù)據(jù)結(jié)構(gòu)+算法組成的代碼來(lái)告訴計(jì)算機(jī)如何執(zhí)行任務(wù)的過(guò)程 , 一個(gè)程序是程序員為了得到一個(gè)任務(wù)結(jié)果而編寫(xiě)的一組指令的集合,正所謂條條大路通羅馬,實(shí)現(xiàn)一個(gè)任務(wù)的方式有很多種不同的方式, 對(duì)這些不同的編程方式的特點(diǎn)進(jìn)行歸納總結(jié)出來(lái)的編程方式類別,即為編程范式。 不同的編程范式本質(zhì)上代表對(duì)各種類型的任務(wù)采取的不同的解決問(wèn)題的思路, 大多數(shù)語(yǔ)言只支持一種編程范式,當(dāng)然也有些語(yǔ)言可以同時(shí)支持多種編程范式。 兩種最重要的編程范式分別是面向過(guò)程編程和面向?qū)ο缶幊獭?/p>
面向過(guò)程 VS 面向?qū)ο?/h2> 面向過(guò)程編程(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step.?
面向過(guò)程編程依賴 - 你猜到了- procedures,一個(gè)procedure包含一組要被進(jìn)行計(jì)算的步驟, 面向過(guò)程又被稱為top-down languages, 就是程序從上到下一步步執(zhí)行,一步步從上到下,從頭到尾的解決問(wèn)題 。基本設(shè)計(jì)思路就是程序一開(kāi)始是要著手解決一個(gè)大的問(wèn)題,然后把一個(gè)大問(wèn)題分解成很多個(gè)小問(wèn)題或子過(guò)程,這些子過(guò)程再執(zhí)行的過(guò)程再繼續(xù)分解直到小問(wèn)題足夠簡(jiǎn)單到可以在一個(gè)小步驟范圍內(nèi)解決。
面向?qū)ο缶幊?Object-Oriented Programming)
OOP編程是利用“類”和“對(duì)象”來(lái)創(chuàng)建各種模型來(lái)實(shí)現(xiàn)對(duì)真實(shí)世界的描述,使用面向?qū)ο缶幊痰脑蛞环矫媸且驗(yàn)樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡(jiǎn)單,并且可以大大提高程序開(kāi)發(fā)效率 ,另外,基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯,從而使團(tuán)隊(duì)開(kāi)發(fā)變得更從容。
面向?qū)ο蟮膸讉€(gè)核心特性如下
Class 類
一個(gè)類即是對(duì)一類擁有相同屬性的對(duì)象的抽象、藍(lán)圖、原型。在類中定義了這些對(duì)象的都具備的屬性(variables(data))、共同的方法
Object 對(duì)象?
一個(gè)對(duì)象即是一個(gè)類的實(shí)例化后實(shí)例,一個(gè)類必須經(jīng)過(guò)實(shí)例化后方可在程序中調(diào)用,一個(gè)類可以實(shí)例化多個(gè)對(duì)象,每個(gè)對(duì)象亦可以有不同的屬性,就像人類是指所有人,每個(gè)人是指具體的對(duì)象,人與人之前有共性,亦有不同
Encapsulation 封裝
在類中對(duì)數(shù)據(jù)的賦值、內(nèi)部調(diào)用對(duì)外部用戶是透明的,這使類變成了一個(gè)膠囊或容器,里面包含著類的數(shù)據(jù)和方法
Inheritance 繼承
一個(gè)類可以派生出子類,在這個(gè)父類里定義的屬性、方法自動(dòng)被子類繼承
Polymorphism 多態(tài)
多態(tài)是面向?qū)ο蟮闹匾匦?簡(jiǎn)單點(diǎn)說(shuō):“一個(gè)接口,多種實(shí)現(xiàn)”,指一個(gè)基類中派生出了不同的子類,且每個(gè)子類在繼承了同樣的方法名的同時(shí)又對(duì)父類的方法做了不同的實(shí)現(xiàn),這就是同一種事物表現(xiàn)出的多種形態(tài)。
編程其實(shí)就是一個(gè)將具體世界進(jìn)行抽象化的過(guò)程,多態(tài)就是抽象化的一種體現(xiàn),把一系列具體事物的共同點(diǎn)抽象出來(lái), 再通過(guò)這個(gè)抽象的事物, 與不同的具體事物進(jìn)行對(duì)話。
對(duì)不同類的對(duì)象發(fā)出相同的消息將會(huì)有不同的行為。比如,你的老板讓所有員工在九點(diǎn)鐘開(kāi)始工作, 他只要在九點(diǎn)鐘的時(shí)候說(shuō):“開(kāi)始工作”即可,而不需要對(duì)銷售人員說(shuō):“開(kāi)始銷售工作”,對(duì)技術(shù)人員說(shuō):“開(kāi)始技術(shù)工作”, 因?yàn)椤皢T工”是一個(gè)抽象的事物, 只要是員工就可以開(kāi)始工作,他知道這一點(diǎn)就行了。至于每個(gè)員工,當(dāng)然會(huì)各司其職,做各自的工作。
多態(tài)允許將子類的對(duì)象當(dāng)作父類的對(duì)象使用,某父類型的引用指向其子類型的對(duì)象,調(diào)用的方法是該子類型的方法。這里引用和調(diào)用方法的代碼編譯前就已經(jīng)決定了,而引用所指向的對(duì)象可以在運(yùn)行期間動(dòng)態(tài)綁定
面向?qū)ο髒s面向過(guò)程總結(jié)
面向過(guò)程的程序設(shè)計(jì)的核心是過(guò)程(流水線式思維),過(guò)程即解決問(wèn)題的步驟,面向過(guò)程的設(shè)計(jì)就好比精心設(shè)計(jì)好一條流水線,考慮周全什么時(shí)候處理什么東西。
優(yōu)點(diǎn)是:極大的降低了寫(xiě)程序的復(fù)雜度,只需要順著要執(zhí)行的步驟,堆疊代碼即可。
缺點(diǎn)是:一套流水線或者流程就是用來(lái)解決一個(gè)問(wèn)題,代碼牽一發(fā)而動(dòng)全身。
面向?qū)ο蟮某绦蛟O(shè)計(jì)的核心是對(duì)象(上帝式思維),要理解對(duì)象為何物,必須把自己當(dāng)成上帝,上帝眼里世間存在的萬(wàn)物皆為對(duì)象,不存在的也可以創(chuàng)造出來(lái)。面向?qū)ο蟮某绦蛟O(shè)計(jì)好比如來(lái)設(shè)計(jì)西游記,如來(lái)要解決的問(wèn)題是把經(jīng)書(shū)傳給東土大唐,如來(lái)想了想解決這個(gè)問(wèn)題需要四個(gè)人:唐僧,沙和尚,豬八戒,孫悟空,每個(gè)人都有各自的特征和技能(這就是對(duì)象的概念,特征和技能分別對(duì)應(yīng)對(duì)象的屬性和方法),然而這并不好玩,于是如來(lái)又安排了一群妖魔鬼怪,為了防止師徒四人在取經(jīng)路上被搞死,又安排了一群神仙保駕護(hù)航,這些都是對(duì)象。然后取經(jīng)開(kāi)始,師徒四人與妖魔鬼怪神仙互相纏斗著直到最后取得真經(jīng)。如來(lái)根本不會(huì)管師徒四人按照什么流程去取。
面向?qū)ο蟮某绦蛟O(shè)計(jì)的
優(yōu)點(diǎn)是:解決了程序的擴(kuò)展性。對(duì)某一個(gè)對(duì)象單獨(dú)修改,會(huì)立刻反映到整個(gè)體系中,如對(duì)游戲中一個(gè)人物參數(shù)的特征和技能修改都很容易。
缺點(diǎn):可控性差,無(wú)法向面向過(guò)程的程序設(shè)計(jì)流水線式的可以很精準(zhǔn)的預(yù)測(cè)問(wèn)題的處理流程與結(jié)果,面向?qū)ο蟮某绦蛞坏╅_(kāi)始就由對(duì)象之間的交互解決問(wèn)題,即便是上帝也無(wú)法預(yù)測(cè)最終結(jié)果。于是我們經(jīng)常看到一個(gè)游戲人某一參數(shù)的修改極有可能導(dǎo)致陰霸的技能出現(xiàn),一刀砍死3個(gè)人,這個(gè)游戲就失去平衡。
應(yīng)用場(chǎng)景:需求經(jīng)常變化的軟件,一般需求的變化都集中在用戶層,互聯(lián)網(wǎng)應(yīng)用,企業(yè)內(nèi)部軟件,游戲等都是面向?qū)ο蟮某绦蛟O(shè)計(jì)大顯身手的好地方。
類的定義
?繼承
# coding=utf-8 class Animal:a_type = "哺乳動(dòng)物"def __init__(self,name,age,sex):self.name = nameself.age = ageself.sex = sexprint("---父類的構(gòu)造方法")def eat(self):print("%s is eating..."% self.name)class Person(Animal): # 繼承a_type = "哺乳高等動(dòng)物"def __init__(self,name,age,sex,hobby):# Animal.__init__(self,name,age,sex)super(Person, self).__init__(name,age,sex) # 效果同上self.hobby = hobbyprint("---子類的構(gòu)造方法")def talk(self):print("person %s is talking...." % self.name)def eat(self):Animal.eat(self) # 先執(zhí)行父類再執(zhí)行子類方法print("人在優(yōu)雅的吃飯。。。") class Dog(Animal):def chase_rabbit(self):print("狗在追兔子。。。")p = Person("Alex",22,"M","女人") # 生成實(shí)例 p.eat() # 調(diào)用父類方法 p.talk() print(p.a_type) print(p.name,p.sex,p.hobby)d = Dog("Mjj",3,"Female") d.eat() d.chase_rabbit() # 調(diào)用子類自有的方法校園管理系統(tǒng)
設(shè)計(jì)一個(gè)培訓(xùn)機(jī)構(gòu)管理系統(tǒng),有總部、分校,有學(xué)員、老師、員工,實(shí)現(xiàn)具體如下需求:
1.有多個(gè)課程,課程要有定價(jià)
2.有多個(gè)班級(jí),班級(jí)跟課程有關(guān)聯(lián)
3.有多個(gè)學(xué)生,學(xué)生報(bào)名班級(jí),交這個(gè)班級(jí)對(duì)應(yīng)的課程的費(fèi)用
4.有多個(gè)老師,可以分布在不同校區(qū),上不同班級(jí)的課
5.有多個(gè)員工,可以分布在不同校區(qū)在總部可以統(tǒng)計(jì)各校區(qū)的賬戶余額、員工人數(shù)、學(xué)員人數(shù)
6.學(xué)生可以轉(zhuǎn)校、退學(xué)
思路:
1,定模型,多少個(gè)類
1)找出關(guān)鍵獨(dú)立名詞:
總部
分校
學(xué)員
老師
員工
課程
班級(jí)
2,定屬性
總部:名稱、地址、電話、網(wǎng)址
財(cái)務(wù)賬戶
員工列表
學(xué)員列表人數(shù)
發(fā)工資
開(kāi)分校
招人
分校:
pass
學(xué)員:姓名、年齡、班級(jí)、余額
上學(xué)打卡
交學(xué)費(fèi)
老師:教學(xué)
員工:姓名、職務(wù)、部門(mén)、工資?
課程:名稱、大綱、價(jià)格
班級(jí):課程、學(xué)期、學(xué)員列表,校區(qū)
3,定關(guān)系
分校---》總部
學(xué)員--》班級(jí)
班級(jí)--》校區(qū)
老師--》班級(jí)
老師--》員工
學(xué)員--》老師
員工--》校區(qū)
4,畫(huà)UML模型圖
統(tǒng)一建模語(yǔ)言
5,寫(xiě)代碼
# coding=utf-8 import datetimeclass School(object):"""總部學(xué)校類"""def __init__(self, name, addr, website):self.name = nameself.addr = addrself.website = websiteself.balance = 0self.branches = [] # 存所有分校對(duì)象self.class_list = [] # 存放班級(jí)列表self.staff_list = [] # 存放員工列表print("創(chuàng)建了校區(qū)[%s],地址[%s]" % (name, addr))def count_stu_num(self):passdef count_stuff_num(self):passdef staff_enrollment(self, staff_obj):self.staff_list.append(staff_obj)print("[%s]入職新員工[%s],職位[%s],部門(mén)[%s]"%(self.name,staff_obj.name,staff_obj.position,staff_obj.dept))def count_total_revenue(self):print("----校區(qū)總收入----")total_rev = self.balanceprint(self.name,self.balance)for b in self.branches:print(b.name,b.balance)total_rev += b.balanceprint("校區(qū)總收入:%s"%total_rev)def count_class_list(self):print("---各校區(qū)班級(jí)---")print(self.name,self.class_list)for i in self.branches:print(i.name, i.class_list)def pay_salary(self):print("開(kāi)始發(fā)工資啦。。。")for i in self.staff_list:i.balance += i.salary # 發(fā)工資self.balance -= i.salary # 總部相應(yīng)賬戶扣錢print("給%s發(fā)了%s,他的余額:%s"%(i.name,i.salary,i.salary))print("公司的余額",self.balance)def __str__(self):return self.namedef __repr__(self):return self.nameclass BranchSchool(School):"""分校"""def __init__(self,name,addr,website,headquarter_obj):super().__init__(name,addr,website)self.headquarter = headquarter_obj # 總部的對(duì)象self.headquarter.branches.append(self) # 把自己加入到總校的校區(qū)列表,建立總部---》分校的反向關(guān)聯(lián)class Course(object):"""課程類"""def __init__(self, name, price, outline):self.name = nameself.price = priceself.outline = outlineprint("創(chuàng)建了課程[%s],學(xué)費(fèi)[%s]" % (name, price))class Class(object):"""班級(jí)"""def __init__(self, course_obj, semester, school_obj):self.course_obj = course_objself.semester = semesterself.school_obj = school_objself.stu_list = [] # 存放學(xué)員列表school_obj.class_list.append(self) # 把自己加到校區(qū)的班級(jí)列表print("校區(qū)[%s]創(chuàng)建了班級(jí)[%s],學(xué)期[%s]" % (school_obj.name, course_obj.name, semester))def stu_transfer(self, stu_obj, new_class_obj):"""學(xué)員轉(zhuǎn)校:param stu_obj: 學(xué)員對(duì)象:param new_class_obj: 轉(zhuǎn)到的新班級(jí)的對(duì)象:return:"""def __str__(self):return "%s-%s-%s學(xué)期" % (self.school_obj.name, self.course_obj, self.semester)def __repr__(self):return "%s-%s-%s學(xué)期" % (self.school_obj.name, self.course_obj, self.semester)class Staff(object):"""員工"""def __init__(self, name, age, balance, salary, position, dept, school_obj):self.name = nameself.age = ageself.balance = balanceself.salary = salaryself.position = positionself.dept = deptself.school_obj = school_objschool_obj.staff_enrollment(self) # 辦入職def punch_card(self):passclass Teacher(Staff):def __init__(self, name, age, balance, salary, position, dept, school_obj, course_obj):super().__init__(name, age, balance, salary, position, dept, school_obj)self.course_obj = course_obj # 老師可以講的課def teach_class(self, class_obj, day):print("老師[%s]正在班級(jí)[%s]上第[%s]天課ing" % (self.name, class_obj, day))class Student(object):"""學(xué)員"""def __init__(self, name, age, balance, class_obj):self.name = nameself.age = ageself.balance = balanceself.class_obj = class_obj# 加入班級(jí)class_obj.stu_list.append(self)# 交學(xué)費(fèi)class_obj.school_obj.balance += class_obj.course_obj.priceself.balance -= class_obj.course_obj.priceprint("班級(jí)[%s]加入了新學(xué)員[%s],交了學(xué)費(fèi)[%s]" % (class_obj, name, class_obj.course_obj.price))def punch_card(self):print("%s:學(xué)員在班級(jí)[%s]上課了...." % (datetime.datetime.now(), self.class_obj))# 創(chuàng)建校區(qū) headquarter = School("老男孩IT教育集團(tuán)", "北京昌平沙河", "oldboyedu.com") sh1_school = BranchSchool("張江校區(qū)", "上海張江", "oldboyedu.com",headquarter) sh2_school = BranchSchool("虹橋校區(qū)", "上海虹橋火車站", "oldboyedu.com",headquarter) sz1 = BranchSchool("騎士計(jì)劃", "深證大學(xué)城", "oldboyedu.com",headquarter) luffy = BranchSchool("路飛學(xué)城", "北京長(zhǎng)安街", "luffycity.com",headquarter)# 創(chuàng)建課程 py_course = Course("Python",21800, None) linux_course = Course("linux", 19800, None) test_course = Course("Testing", 19800, None) go_course = Course("GO", 22800, None) # 創(chuàng)建班級(jí) py_24 = Class(py_course, 24, headquarter) go_5 = Class(go_course, 5, headquarter) py_12 = Class(py_course, 12, sh1_school) linux_63 = Class(linux_course, 63, sz1)# 創(chuàng)建員工,老師,學(xué)員 s1 = Staff("Alex", 26, 0, 4000, "CEO", "總經(jīng)辦", luffy) s2 = Staff("Todd", 45, 0, 60000, "CEO", "總經(jīng)辦", headquarter) s3 = Staff("明月", 24, 0, 7000, "HR", "HR", headquarter)t1 = Teacher("日天", 28, 0, 30000, "講師", "教學(xué)部", sz1, py_course) t2 = Teacher("Egon", 28, 0, 30000, "講師", "教學(xué)部", sh1_school, go_course) t3 = Teacher("佩奇", 29, 0, 40000, "學(xué)科帶頭人", "教學(xué)部", headquarter, linux_course)stu1 = Student("春生", 22, 50000, py_24) stu2 = Student("black_girl", 22, 30000, go_5) stu3 = Student("小強(qiáng)", 22, 35000, go_5) stu4 = Student("小虎", 28, 38000, linux_63)print(headquarter.balance) print(sz1.balance) print(headquarter.branches) # 統(tǒng)計(jì)總收入,學(xué)員人數(shù) headquarter.count_total_revenue() headquarter.count_class_list() headquarter.pay_salary() View Code總結(jié)
以上是生活随笔為你收集整理的第一章 面向对象编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql新
- 下一篇: 第二章 面向对象进阶