python之路--day21--組合與封裝
阿新 • • 發佈:2018-04-13
color ice chan 函數 DC cor pla linux 方案
講在組合之前:
解決類和類之間代碼冗余問題有兩種解決方案:1,繼承 2,組合
1,繼承:描述的是類和類之間,什麽是什麽的關系,一種從屬關系
2,組合:描述的是類和類之間的關系。是一種什麽有什麽的關系
組合:一個類產生的對象,該對象擁有一個屬性,這個屬性的值來自於另外一個類的對象
class OldboyPeople: school = ‘oldboy‘ def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex類的組合class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,level,salary): super().__init__(name,age,sex) self.level=level self.salary = salary def change_score(self): print(‘......................‘) class OldboyTeacher(OldboyPeople):def __init__(self,name,age,sex,course): super().__init__(name,age,sex) self.course = course def change_score(self): print(‘......................‘) tea1 = OldboyTeacher(‘egon‘,18,‘male‘,9,3.1) data_obj = Data(2000,1,1) tea1.birth = data_obj ## ## 此處:為tea1對象新增了一個屬性birth,這個屬性的值是Data實例化的對象data_obj....這就是類的組合## ##
class OldboyPeople: school = ‘oldboy‘ def __init__(self, name, age, sex,): self.name = name self.age = age self.sex = sex class OldboyTeacher(OldboyPeople): def __init__(self,name,age,sex,level,salary): super().__init__(name,age,sex) self.level=level self.salary=salary self.courses=[] def change_score(self): print(‘teacher %s is changing score‘ %self.name) def tell_course_info(self): print((‘老師%s 教授的課程信息如下‘ %self.name).center(50,‘=‘)) for course_obj in self.courses: course_obj.info() class Oldboystudent(OldboyPeople): def __init__(self,name,age,sex): super().__init__(name,age,sex,) self.courses=[] def choose(self): print(‘student %s choose course‘ %self.name) def tell_course_info(self): print((‘學生%s 學習的課程信息如下‘ % self.name).center(50, ‘=‘)) for course_obj in self.courses: course_obj.info() class Course: def __init__(self,cname,period,price): self.cname=cname self.period=period self.price=price def info(self): print(‘課程信息<名字:%s 周期:%s 價錢:%s>‘ %(self.cname,self.period,self.price)) tea1=OldboyTeacher(‘egon‘,18,‘male‘,9,3.1) stu1=Oldboystudent(‘張三‘,16,‘male‘) python=Course(‘Python全棧開發‘,‘5mons‘,3000) linux=Course(‘Linux高級架構師‘,‘5mons‘,2000) go=Course(‘Go開發工程師‘,‘3mons‘,1000) # # 給老師添加課程 # tea1.courses.append(python) # tea1.courses.append(linux) # print(tea1.courses) # tea1.courses[0].info() # for course_obj in tea1.courses: # course_obj.info() # tea1.tell_course_info() # 給學生添加課程 stu1.courses.append(python) stu1.courses.append(go) stu1.courses.append(linux) stu1.tell_course_info()組合練習
封裝:
什麽是封裝:
裝就是把一堆屬性存起來,封就是把這些屬性給隱藏起來
強調:封裝單從字面意思看就等同於隱藏,但其實封裝絕對不是單純意義的隱藏
為什麽要用封裝:
最終目的:明確區分內外,對內部開發,對外部隱藏
封裝數據屬性的目的:把數據屬性封裝起來,然後需要開辟接口給類外部的使用者使用。然後在接口上添加控制邏輯,
從而嚴格控制訪問者對屬性的操作
class People: def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print(self.__name,self.__age) def set_info(self,name,age): if type(name) is not str: raise TypeError(‘用戶名必須為str類型‘) if type(age) is not int: raise TypeError(‘年齡必須為int類型‘) self.__name=name self.__age=age數據屬性的封裝
封裝函數屬性的目的:隔離復雜度
class ATM: def __card(self): print(‘插卡‘) def __auth(self): print(‘用戶認證‘) def __input(self): print(‘輸入取款金額‘) def __print_bill(self): print(‘打印賬單‘) def __take_money(self): print(‘取款‘) def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() obj=ATM() obj.withdraw()函數屬性的封裝
如何用封裝
在屬性前面就是 __開頭(一定註意不要加__結尾)
特征:1,__開頭隱藏屬性,只是語法上的一種變形,對外不對內
什麽是對外不對內:為一個屬性加__開頭,會在類定義階段將屬性名統一變形為:_ 自己的類名__ 屬性名
class Foo: __x=1111 #_Foo__x=1111 def __init__(self,y): self.__y=y #self._Foo__y=y def __f1(self): #_Foo__f1 print(‘Foo.f1‘) def get_y(self): print(self.__y) # print(self._Foo__y) #類內部在定義階段全部做了語法上的修改,所以內部可以訪問__開頭的屬性 #但是類外部無法直接通過屬性名訪問類內部屬性__開頭封裝類屬性
2,這種語法上的變形,只在類定義階段生效一次,定義階段之後再定義的__開頭的屬性,沒有隱藏的效果
# Foo.__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1 # print(Foo.__dict__) # obj.__bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=2 # print(obj.__dict__)類定義之後再定義的__開頭
3,如果父類不想子類覆蓋掉自己的屬性,可以在定義階段在使用__開頭,隱藏屬性、
class Foo: def __f1(self): #_Foo__f1 print(‘Foo.f1‘) def f2(self): print(‘Foo.f2‘) self.__f1() #obj._Foo__f1() class Bar(Foo): def __f1(self): #_Bar__f1 print("Bar.f1") obj=Bar() obj.f2()不讓子類覆蓋父類的同名屬性
python之路--day21--組合與封裝