一、组合 解决类与类之间代码冗余问题有两种解决方案: 1、继承 2、组合 1、继承:描述的是类与类之间,从属关系 2、组合:描述的是类与类之间的关系,是一种什么有什么关系 一个类产生的对象,该对象拥有一个属性,这个属性的值是来自于另外一个类的对象 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) tea1.birth=date_obj stu1=Oldboystudent(‘张三‘,16,‘male‘,‘linux‘) stu1.birth=Date(2002,3,3) stu1.birth.tell_birth() 二、封装 什么是封装 装就是把一堆属性存起来,封的概念就把这些属性给隐藏起来 强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏 如何把属性隐藏起来,就在属性前面加上__开头(注意不要加__结尾) 注意: 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) obj=Foo(22222) print(obj.x) print(obj.__x) obj.__f1() print(obj.y) print(obj.__y) print(Foo.__dict__) print(obj._Foo__x) print(obj._Foo__y) obj._Foo__f1() obj.get_y() 2、这种语法意义上变形,只在类定义阶段发生一次,类定义之后,新增的__开头的属性都没有变形的效果 Foo.__aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1 print(Foo.__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() 强调:封装单从字面意思去看等同于隐藏,但其实封装绝对不是单纯意义的隐藏 2、为什么要用封装 1 封装数据属性的目的:把数据属性封装起来,然后需要开辟接口给类外部的使用者使用,好处是我们可以在接口之上添加控制逻辑,从而严格空间访问者对属性的操作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‘) #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() obj=ATM()obj.withdraw() 封装的终极奥义:明确地区分内外,对外是隐藏的,对内是开放的
原文地址:https://www.cnblogs.com/zhaodafa/p/8823866.html
时间: 2024-11-15 06:15:52