1. 程式人生 > >python之路--day21--組合與封裝

python之路--day21--組合與封裝

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--組合與封裝