面向对象的组合,多态
组合
什么是组合
对象的某个属性是另一个类的对象
组合的概念
class Foo:
def __init__(self,bar):
self.bar=bar
class Bar:
pass
#f=Foo()
bar=Bar()
#f=Foo(Bar())
f=Foo(bar)
为什么使用组合?
可以减少代码冗余
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):
def __init__(self,name,age,course):
self.name=name
self.age=age
# course是课程对象,表示学生选的课程
self.course = course
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',20180,7)
stu=Student('nick',19,course)
teacher=Teacher('nick',19,'高级',course)
#查看老师教授的课程名
print(teacher.course.name)
查看stu1选的所有课程名称
方式一:通过普通函数
class Person:
school='oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course):
self.name=name
self.age=age
self.level=level
self.course=course
class Student(Person):
def __init__(self,name,age):
self.name=name
self.age=age
##course是课程对象,表示学生选的课程
self.course_list=[]
def choose_course(self,course):
self.course_list.append(course)
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))
def tell_all_course(student):
for course in student.course_list:
print(course.name)
tell_all_course(stu2)
方式二:通过对象的绑定方法
class Person:
school='oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course):
self.name=name
self.age=age
self.level=level
self.course=course
class Student(Person):
def __init__(self,name,age):
self.name=name
self.age=age
##course是课程对象,表示学生选的课程
self.course_list=[]
def choose_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))
stu1.tell_all_course()
stu2.tell_all_course()
多态
什么是对态?
多态数据类型有形态:字符串,列表,元祖
多态性:多态性是指在不考虑实例类型的情况下使用实例
好处:
增加了程序的灵活性
增加了程序的可扩展性
多态性基础
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数,在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法),也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数
class Animal:
def speak(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
class Dog(Animal):
def speak(self):
print('汪汪')
pig=Pig()
dog=Dog()
pig.speak()
dog.speak()
简化版:
#第一种方式:用abc实现接口统一化,约束代码(用的比较少)
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
class Dog(Animal):
def YY(self):
print('汪汪')
# dog=Dog()
# dog.YY() ##这样就不能利用多态性
def animal_speak(obj):
obj.speak()
pig=Pig()
##第二种方式,用异常处理来实现(常用)
class Animal():
def speak(self):
raise Exception('你得给我重写它啊')
class Pig(Animal):
def speak(self):
print('哼哼哼')
class People(Animal):
print('say hello')
pig=Pig()
pe=People()
def annimal_speak(obj):
obj.speak()
annimal_speak(pig)
linux一切皆文件
##鸭子类型的写法
##内存类
class Memory:
def read(self):
print('memory...read')
def write(self):
print('memory...write')
class Network:
def read(self):
print('network...read')
def write(self):
print('network...write')
def read(obj):
obj.read()
m=Memory()
n=Network()
read(n)
read(m)
多态性的好处:
1、增加了程序的灵活性:以不变应万变,不论对象千变万化,使用者都是同一种形式调用,如func(animal)
2、增加程序可扩展性:通过继承Animal类创建一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
封装
封装是什么意思?
从封装本身的意思去理解,封装好像是拿来一个麻袋,把小猫,小狗等一起装进麻袋,然后把麻袋封上口子
如何隐藏:
把东西包装进去之后,隐藏起来,外部访问不到
如何用代码实现隐藏:
隐藏属性/隐藏方法隐藏之后,外部访问不到,只有内部能够访问
隐藏属性:通过__变量名来隐藏
隐藏方法:通过__方法名来隐藏
隐藏属性是为了安全
class Person:
def __init__(self,name,age):
self._name=name
self._age=age
def set_name(self,name):
self._name=name
p=Person('nick',18)
_p_name="sss"
# p.set_name('6688') ##修改了姓名
print(p.__dict__)
print(p._name) ##获取姓名
多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度)
多态性:一种调用方式,不同的执行效果(多态性)
property特性
property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接使用
class FOO:
def func(self):
pass
#定义property属性
@property
def prop(self):
pass
foo_obj=FOO()
foo_obj.func()
foo_obj.prop
class Goods(object):
@property
def size(self):
return 100
g=Goods()
print(g.size)
property属性的定义和调用要注意一下几点:
1、定义时,在实例方法的基础上添加@property装饰器;并且仅有一个self参数
2、调用时,无需括号