组合与封装

第1章 组合与封装

作用:

解决类与类之间代码冗余问题有两种解决方案:1、继承 2、组合

继承:描述的是类与类之间,什么是什么的关系

 

 

1.1 组合

组合:描述的是类与类之间的关系,是一种什么有什么关系

一个类产生的对象,该对象拥有一个属性,这个属性的值是来自于另外一个类的对象

 

组合练习示例:

class Date:

    def __init__(self,year,mon,day):

        self.year = year

        self.mon = mon

        self.day = day

 

    def tell_birth(self):

        print('出生年月日<%s-%s-%s>' % (self.year, self.mon, self.day))

 

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('teacher %s is changing score' %self.name)

 

class Oldboystudent(OldboyPeople):

    def __init__(self,name,age,sex,course,):

        super().__init__(name,age,sex,)

        self.course=course

 

    def choose(self):

        print('student %s choose course' %self.name)

 

 

tea1=OldboyTeacher('egon',18,'male',9,3.1)

date_obj=Date(2000,1,1)

# date_obj.tell_birth()

 

tea1.birth=date_obj

# print(tea1.birth)

# tea1.birth.tell_birth()

# tea1.change_score()

 

stu1=Oldboystudent('张三',16,'male','linux')

stu1.birth=Date(2002,3,3)

stu1.birth.tell_birth()

 
View Code

1.2 如何封装

1.2.1 什么是封装?

装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来

强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏

 

1.2.2 为什么要用封装?

1、          封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作

2、          封装函数属性的目的:为了隔离复杂度

3、          封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的

1.2.3 如何用封装?

示例:

# class People:

#     def __init__(self,name,age):

#         self.__name=name

#         self.__age=age

#

#     def tell_info(self):

#         # u=input('user>>: ').strip()

#         # p=input('pwd>>: ').strip()

#         # if u == 'egon' and p == '123':

#             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

#

# p=People('egon',18)

#

# # p.tell_info()

# # p.tell_info()

#

# # p.set_info('EGON',19)

# # p.tell_info()

#

# # p.set_info(353535353535353535,20)

# p.set_info('EGON','20')

 
View Code

示例:

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()

 
View Code

第2章 封装之property

BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)

成人的BMI数值:

过轻:低于18.5

正常:18.5-23.9

过重:24-27

肥胖:28-32

非常肥胖, 高于32

  体质指数(BMI)=体重(kg)÷身高^2(m)

  EX:70kg÷(1.75×1.75)=22.86

示例:

class People:
    def __init__(self,name,weight,height):
        self.name=name
        self.weight=weight
        self.height=height

    @property
    def bmi(self):
        return self.weight / (self.height * self.height)

egon=People('egon',75,1.80)
# egon.bmi = egon.weight / (egon.height * egon.height)   ##加上@property 这条会报错
print(egon.bmi)

yl=People('yangli',85,1.74)
# yl.bmi=yl.weight / (yl.height * yl.height)   ##加上@property 这条会报错
print(yl.bmi)
View Code

 

2.1 讲解

首先需要明确。bmi是算出来的,不是一个固定死的值,也就说我们必须编写一个功能,每次调用该功能都会立即计算一个值.

egon=People('egon',75,1.80)

yl=People('yangli',85,1.74)

 

但很明显人的bmi值听起来更像一个名词而非动词

print(egon.bmi())

print(yl.bmi())

 

 

于是我们需要为bmi这个函数添加装饰器,将其伪装成一个数据属性

egon.weight=70

print(egon.bmi) #21.604938271604937,调用egon.bmi本质就是触发函数bmi的执行,从而拿到其返回值

print(yl.bmi)
View Code

2.2 了解

# egon.bmi=123 # egon.bmi背后对应的是一个函数,所以不能赋值

class People:

    def __init__(self,name):

        self.__name=name

 

 

    @property

    def name(self): #obj.name

        print('您现在访问的是用户名。。。')

        return self.__name

 

    @name.setter #obj.name='EGON'

    def name(self,x):

        # print('=================',x)

        if type(x) is not str:

            raise TypeError('名字必须是str类型,傻叉')

        self.__name=x

 

    @name.deleter

    def name(self):

        # print('就不让你删')

        del self.__name

 

obj=People('egon')

 

# print(obj.name)

# print(obj.name())

 

# print(obj.name)

 

# obj.name='EGON'

 

# print(obj.name)

 

# obj.name=123

 

del obj.nam
View Code

 

posted @ 2018-05-14 18:49  Jacob先生  阅读(147)  评论(0编辑  收藏  举报