python面向对象之组合及封装

一,组合

'''
1、什么是组合
    对象的属性的值是来自于另外一个类的对象,这就叫类的组合使用
2、为何要用组合
    组合是用来减少类与类代码冗余的

    组合vs继承
        只有在类与类之间有从属的关系的时候才能用继承
        否则的话用组合


3、如何用组合


'''
# import pickle
# class OldboyPeople:
#     school = 'oldboy'
#
#     def __init__(self,name,age,sex):
#         self.name=name
#         self.age=age
#         self.sex=sex
#
#     def save(self):
#         with open('%s' % self.name, 'wb') as f:
#             pickle.dump(self, f)
#
# class OldboyStudent(OldboyPeople):
#     def __init__(self,name,age,sex):
#         OldboyPeople.__init__(self,name,age,sex)
#         self.courses=[]
#
#     def choose_course(self,course):
#         print('%s is choosing course:%s' %(self.name,course))
#
#
# class OldboyTeacher(OldboyPeople):
#     def __init__(self,name,age,sex,level):
#         # self.name = name
#         # self.age = age
#         # self.sex = sex
#         OldboyPeople.__init__(self,name,age,sex)
#         self.level=level
#
#     def score(self,stu):
#         print('%s is score %s' %(self.name,stu.name))
#
#
# stu1=OldboyStudent('李三泡',18,'male')
# # print(stu1.courses)
# stu1.courses.append({'name':'python','price':8000,'period':'5mons'})
# stu1.courses.append({'name':'linux','price':10000,'period':'3mons'})
# print(stu1.courses)
#
# for course in stu1.courses:
#     print("""
#     课程名:%s
#     价钱:%s
#     周期:%s
#     """ %(course['name'],course['price'],course['period']))
#
#
# stu2=OldboyStudent('李二泡',38,'female')
# stu2.courses.append({'name':'python','price':8000,'period':'5mons'})
# for course in stu2.courses:
#     print("""
#     课程名:%s
#     价钱:%s
#     周期:%s
#     """ %(course['name'],course['price'],course['period']))


#改正
import pickle
class OldboyPeople:
    school = 'oldboy'

    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

    def save(self):
        with open('%s' % self.name, 'wb') as f:
            pickle.dump(self, f)

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex):
        OldboyPeople.__init__(self,name,age,sex)
        self.courses=[]

    def choose_course(self,course):
        print('%s is choosing course:%s' %(self.name,course))

    def tell_courses_info(self):
        for course in self.courses:
            course.tell_info()

class OldboyTeacher(OldboyPeople):
    def __init__(self,name,age,sex,level):
        # self.name = name
        # self.age = age
        # self.sex = sex
        OldboyPeople.__init__(self,name,age,sex)
        self.level=level

    def score(self,stu):
        print('%s is score %s' %(self.name,stu.name))


class Course:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period

    def tell_info(self):
        print("""
            课程名:%s
            价钱:%s
            周期:%s
            """ % (self.name, self.price, self.period))

python=Course('python',8000,'5mons')
linux=Course('linux',10000,'3mons')

stu1=OldboyStudent('李三泡',18,'male')
stu1.courses.append(python)
stu1.courses.append(linux)


stu2=OldboyStudent('李二泡',38,'female')
stu2.courses.append(python)


stu1.tell_courses_info()
stu2.tell_courses_info()

二封装

'''
1、什么是封装
    “装”的意思就往一个容器中放入一系列属性
    “封”的意思就是藏起来,在内部可以看到,但对外部是隐藏的

2、为什么要用封装

3、如何用封装
    但凡是双下划线开头(不能是双下划线结尾)的属性,会被隐藏起来,类内部可以直接使用
    而类外部无法直接使用,即封装是对外不对内的

    这种隐藏的特点:
        1、只是一种语法上的变形,会将__开头的属性变形为:_自己的类名__属性名
        2、该变形只在类定义阶段发生一次,在类定义阶段之后新增的__开头的属性并不会发生变形
        3、隐藏是对外不对内的
        4、在继承中,父类如果不想让子类覆盖自己的同名方法,可以将方法定义为私有的

'''
# class Foo:
#     __n=1 #_Foo__n=1
#
#     def __init__(self,name):
#         self.__name=name #self._Foo__name=name
#
#     def __f1(self): #_Foo__f1
#         print('f1')


# print(Foo.__n)
# print(Foo.__f1)

# obj=Foo('egon')
# print(obj.__name)
# print(obj.__dict__)

# print(Foo.__dict__)
# print(Foo._Foo__n)
# print(Foo._Foo__f1)

# Foo.__x=222
# print(Foo.__dict__)
# print(Foo.__x)

# obj.__age=18
# print(obj.__dict__)


# class Foo:
#     __n=1 #_Foo__n=1
#
#     def __init__(self,name):
#         self.__name=name #self._Foo__name=name
#
#     def __f1(self): #_Foo__f1
#         print('f1')
#
#     def f2(self):
#         self.__f1() #self._Foo__f1()
#         print(self.__name) #self._Foo__name
#         print(self.__n) #self._Foo__n
#
#
# obj=Foo('egon')
# obj.f2()
# print(obj.__name)

# class Foo:
#     def __f1(self): #_Foo__f1
#         print('Foo.f1')
#
#     def f2(self):
#         print('Foo.f2')
#         self.__f1() #self._Foo__f1()
#
#
# class Bar(Foo):
#     def __f1(self): #_Bar__f1
#         print('Bar.f1')
#
#
# obj=Bar()
# obj.f2()


# 为何要封装
#1、封装数据属性:将数据数据隐藏起来,从而类的使用者无法直接操作该数据属性
#需要类的设计者在类内部开辟接口,让类的使用者同接口来间接地操作数据,
#类的设计者可以在接口之上附加任意逻辑,从而严格控制类的使用者对属性的操作
# class People:
#     def __init__(self,name,age):
#         self.__name=name
#         self.__age=age
#
#     def tell_info(self):
#         print('<%s:%s>' %(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.set_info('egon','asdfsadf')
# # p.tell_info()


#2、封装函数属性:隔离复杂度

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

a=ATM()
a.withdraw()

  

posted @ 2018-05-28 13:44  cyh追梦寻  阅读(97)  评论(0)    收藏  举报