56923

day25 类的组合、多态和封装

昨日回顾:
-继承
-如何使用
-通过继承来减少代码冗余
-如何重用父类的方法一
-属性查找顺序
-如何重用父类的方法二
-派生
今日内容:
-组合
-什么时候用组合,什么时候用继承
-什么是什么的关系用继承
-什么有什么的关系用组合
-多态和多态性

​ -封装

<h2 id="一组合">一、组合</h2>

什么是组合:对象的某个属性是另一个类的对象

# 组合的概念 class Foo: def __init__(self, bar): self.bar = bar class Bar: pass bar = Bar() f = Foo(bar) # 为什么使用组合: 可以减少代码冗余 class Person: school = 'old_boy' class Teacher(Person): def __init__(self, name, level, course): self.name = name self.level = level # course是课程对象,表示老师教授的课程 self.course = course class Student(Person): def __init__(self, name, course): self.name = name # course是课程对象,表示学生选的课程 self.course = course class Course: def __init__(self, course_name, course_price): self.course_name = course_name self.course_price = course_price course = Course('Python', 20000) stu = Student('nick', course) teacher = Teacher('nick', '高级', course) print(stu.course.name) print(teacher.course.name) # 组合的应用 class Person: school = 'oldboy' class Teacher(Person): def __init__(self,name,age,level,course): self.name=name self.age=age self.level=level #course是课程对象,表示老师教授的课程 self.course=course class Student(Person): # course=[] #错误 def __init__(self,name,age): self.name=name self.age=age # course是课程对象,表示学生选的课程 self.course_list = [] def choose_course(self,course): # self.course=[] #错误 #把课程对象追加到学生选课的列表中 self.course_list.append(course) def tell_all_course(self): #循环学生选课列表,每次拿出一个课程对象 for course in self.course_list: #课程对象.name 取到课程名字 print(course.name) class Course: def __init__(self,course_name,course_price,course_period): self.name=course_name self.price=course_price self.period=course_period course=Course('Python',20199,7) stu1=Student('nick',19) stu1.choose_course(course) stu2=Student('王二丫',19) stu2.choose_course(course) stu2.choose_course(Course('linux',19999,5)) <h2 id="二多态与多态性">二、多态与多态性</h2>

什么是多态:一类事物的多种形态

多态性:多态性是指在不考虑实例类型的情况下使用实例

好处:1. 增加了程序的灵活性。

​ 2.增加了程序的可扩展性。

# 多态基础 class Animal: def speak(self): pass class Pig(Animal): def speak(self): print('哼哼哼') class Dog(Animal): def speak(self): print('汪汪') class People(Animal): def Speak(self): print('say hello') pig = Pig() dog = Dog() def animal_speak(obj): obj.speak() animal_speak(pig) animal_speak(dog) # 两种约束代码的方式 # 第一种:用abc模块实现接口统一化,约束代码(用的比较少) # 第二种:用异常处理来实现(常用) class Animal(): def speak(self): #主动抛出异常 raise Exception('你得给我重写它啊') class Pig(Animal): def speak(self): print('哼哼哼') class People(Animal): def speak(self): print('say hello') pig=Pig() pe=People() def animal_speak(obj): obj.speak() animal_speak(pig) animal_speak(pe) # 崇尚鸭子类型:只要走路像鸭子(对象中有某个绑定方法),那你就是鸭子 <h2 id="三封装">三、封装</h2>

封装是什么:封装就好像是拿来一个麻袋,把小猫,小狗,小王八,一起装进麻袋,然后把麻袋封上口子,然后隐藏起来,外部访问不到。

如何用代码实现隐藏:

​ 隐藏属性/隐藏方法,隐藏之后,外部访问不到,只有内部能访问

​ # 隐藏属性: 通过 __变量名来隐藏

​ # 隐藏方法: 通过 __方法名来隐藏

# name隐藏起来,隐藏属性是为了安全 class Person: def __init__(self, name, age): self.__name = name self.__age = age def get_name(self): print(self.__name) p = Person('nick', 89) print(p.age) print(p.get_name()) # 通过变形隐藏了属性 # 隐藏的属性在python还是能够在外部访问,但是一般不这么做 print(p.__Person__name) print(p.__dict__) # 隐藏方法:隔离复杂度 class Person: def __init__(self, name, age): self.__name = name self.__age = age def __speak(self): print('wangwang') p = Person('nick', 89) p.__speak() print(Person.__dict__) P._Person__speak() # 什么时候属性变形,只要在类内部,以__变量名 命名的变量,都会被隐藏,会发生变形,在外部放 # 入的__变量名 属性是不会隐藏的 # 计算人的bmi指数 # property装饰器:把方法包装成数据属性 class Person: def __init__(self, name, height, weight): self.name = name self.height = height self.weight = weight @property def bmi(self): return self.weight/(self.hetght ** 2) p = Person('lqz', 1.82, 70) print(p.bmi) # property之setter和deleter class Person: def __init__(self,name,height,weight): self.__name=name self.__height=height self.__weight=weight @property def name(self): return '[我的名字是:%s]'%self.__name #用property装饰的方法名.setter @name.setter def name(self,new_name): # if not isinstance(new_name,str): if type(new_name) is not str: raise Exception('改不了') if new_name.startswith('sb'): raise Exception('不能以sb开头') self.__name=new_name # 用property装饰的方法名.deleter @name.deleter def name(self): # raise Exception('不能删') print('删除成功') # del self.__name p=Person('lqz',1.82,70) print(p.name) p.name = 'pppp' p.name = 999 p.name = 'sb_nick'

来源:博客园

作者:17vv

链接:https://www.cnblogs.com/17vv/p/11425736.html

Recommend