ʕ·͡ˑ·ཻʔ Daisy 🐾 ◟̆◞̆♥︎
Zou-Wang
点击头像关注

三っ•̀.̫•́)っ 我去宇宙了 ⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾

面向对象的组合,多态

组合

什么是组合

​ 对象的某个属性是另一个类的对象

组合的概念

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、调用时,无需括号

posted @ 2019-09-07 17:11  没忘  阅读(110)  评论(0编辑  收藏  举报