zoukankan      html  css  js  c++  java
  • 第一阶段:Python开发基础 day25 面向对对象三大特性之多态和封装、组合

    上节课内容回顾

    #1 如何使用继承
    #基类,父类
    class Person:
        school='oldboy'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    #子类,派生类
    class Student(Person):
        pass
    stu=Student('nick',18)
    
    #2 通过继承减少代码冗余
    class Person:
        school='oldboy'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    #子类,派生类
    
    class Student(Person):
        def __init__(self,name,age,course):
            #如何重用父类的方法
            Person.__init__(self,name,age)
            #严重错误的Person() 是实例化,产生对象,对象调用自己的绑定方法__init__
            Person().__init__()
            ss=Person()   
            # ss.__init__(name,age,course)
            self.course=course
    
    #属性查找顺序
    #原来:对象--->类--->报错
    #学了继承:对象--->类--->父类--->父类......---->报错
    #父类的查找顺序
    #多层继承查找顺序:一条线往上找到底
    #多继承(横向):从左往右的顺序
    #横向的多层继承
        # -不形成菱形:从左侧开始一直往上找到底,再从左侧第二个开始往上找到底...
        #-形成菱形:
            #  -新式类:继承了object的类(以及它的子类)都叫新式类,py3中都是新式类,因为默认都继承了object,py2中需要手动的继承object
            #  -经典类:py2中没有继承object的就是经典类
            #  -新式类:广度优先,菱形的顶点最后才找
            #  -经典类:深度优先,菱形顶点在第一次分支就找到
    #如何重用父类的方法二
    #通过super关键字
    class Person(object):
        school = 'oldboy'
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def study(self):
            print('study....')
    
    class Student(Person):
        school = 'yyyy'
        def __init__(self,name,age,course):
            #相当于生成了一个特殊对象,对象调用绑定方法,不需要传第一个参数
            #严格按照继承的查找顺序(mro列表找得)
            super().__init__(name,age)
            self.course=course
        def study(self):
            # Person.study(self)
            super().study()
            # print("%s学生在学习"%self.name)
    		#派生
    

    今日学习内容

    一、组合

    1.1 什么是组合

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

    组合的概念:

    class Foo:
        def __init__(self,bar):
            self.bar=bar
            
    class Bar:
        pass
    # f=Foo()
    bar=Bar()
    # f=Foo(Bar())
    f=Foo(bar)
    

    1.2 为什么使用组合

    ​ 可以减少代码冗余

    不使用组合方法:

    class Person:
        school = 'oldboy'
    
    class Teacher(Person):
        def __init__(self,name,age,level,course_name,course_price,course_period):
            self.name=name
            self.age=age
            self.level=level
    
    class Student(Person):
        def __init__(self,name,age,course,course_name,course_price,course_period):
            self.name=name
            self.age=age
            self.course=course
    

    使用组合方法:

    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)
    

    1.3 如何使用组合

    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))
    
    
    #查看stu1选的所有课程名称
    #方式一(通过普通函数)
    # def tell_all_course(student):
    #     for course in student.course_list:
    #         print(course.name)
    #
    # # tell_all_course(stu1)
    # tell_all_course(stu2)
    
    #方式二(通过对象的绑定方法)
    # stu1.tell_all_course()
    stu2.tell_all_course()
    

    1.4 扩展部分

    组合和继承

    • 什么时候用组合,什么时候用继承

      • 什么是什么的关系用继承
      • 什么有什么的关系用组合

    二、多态和多态性

    2.1 什么是多态?

    ​ 一类事物的多种形态

    ​ 比如:动物类:人、猫、狗

    2.2 多态性

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

    2.3 使用多态的好处

    ​ 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()
    people=People()
    pig.speak()
    dog.speak()
    people.speak()
    
    
    def animal_speak(obj):
        obj.speak()
    animal_speak(pig)
    animal_speak(people)
    
    
    def len(obj):
        return obj.__len__()
    len('xxxx')
    len([1,2,3])
    

    2.4 两种约束代码的方式

    第一种方式:用abc实现接口统一化,约束代码(用的比较少)

    import abc
    # 第一在括号中写metaclass=abc.ABCMeta
    class Animal(metaclass=abc.ABCMeta):
        # 第二在要约束的方法上,写abc.abstractmethod装饰器
        @abc.abstractmethod
        def speak(self):
            pass
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
    class Dog(Animal):
        def yy(self):
            print('汪汪')
    
    class People(Animal):
        def zz(self):
            print('say hello')
    
    
    people = People()
    people.zz()
    # 这样就不能利用多态性
    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):
        def speak(self):
            print('say hello')
    pig=Pig()
    pe=People()
    def animal_speak(obj):
        obj.speak()
    
    animal_speak(pig)
    animal_speak(pe)
    

    2.5 鸭子类型

    ​ 鸭子类型:只要走路像鸭子(对象中有某个绑定方法),那你就是鸭子

    # 鸭子类型的写法
    
    # 内存类
    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(m)
    read(n)
    

    三、封装

    3.1 封装是什么意思?

    ​ 从封装本身的意思去理解:

    ​ 封装就好像是拿一个麻袋,把小猫,小狗等,一起装进麻袋,然后把麻袋封上口子

    3.2 如何隐藏

    ​ 把东西包装进去之后,隐藏起来,外部访问不到

    3.3 如何用代码实现隐藏

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

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

    • 隐藏方法:通过__方法名来隐藏

      隐藏属性主要是为了安全

    #name 隐藏起来
    # class Person:
    #     def __init__(self,name,age):
    #         self.__name=name
    #         self.__age=age
    #     def get_name(self):
    #         # print(self.__name)
    #         return '[----%s-----]'%self.__name
    #
    # p=Person('nick',89)
    # print(p.age)
    #访问name
    # print(p.name)
    # print(p.__name)
    # print(p.get_name())
    #隐藏的属性访问不到?实际上有方法能访问到
    #通过变形隐藏了属性
    # print(p._Person__name)
    
    # print(p.__dict__)
    
    #隐藏方法:隔离复杂度
    
    # class Person:
    #     def __init__(self,name,age):
    #         self.__name=name
    #         self.__age=age
    #     def __speak(self):
    #         print('6666')
    #
    # p=Person('nick',89)
    # p.__speak()
    # print(Person.__dict__)
    # p._Person__speak()
    
    #什么时候属性变形,只要再类内部,以__变量名 命名的变量,都会被隐藏,会发生的变形,在外部放入的  __变量名 属性是不隐藏的
    # class Person:
    #     def __init__(self,name,age):
    #         self.__name=name
    #         self.__age=age
    #     def set_xx(self,xx):
    #         self.__xx=xx
    #
    # p=Person('nick',18)
    # # ._p_xx="xxx"
    #
    # p.set_xx('6688')
    # print(p.__dict__)
    

    今日总结

    暂无

  • 相关阅读:
    C语言I博客作业06
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业03
    C语言I博客作业02
    第一次作业
    C语言I博客作业09
    C语言I博客作业08
    C语言I博客作业07
    C语言I博客作业06
  • 原文地址:https://www.cnblogs.com/foreversun92/p/11425573.html
Copyright © 2011-2022 走看看