• 面向对象


    1. 组合

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

    # 组合的概念
    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_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)
    

    如何使用组合

    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('wey',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()
    

    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)
    
    # 第一种方式:用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 Dog(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 Dog(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)
    
    # 崇尚鸭子类型:只要走路像鸭子(对象中有某个绑定方法,那你就是鸭子)
    
    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)
    
    # linux 一切皆文件
    # 传统写法
    class File:
        def read(self):
            pass
        def write(self):
            pass
    # 内存类
    class Memory(File):
        def read(self):
            print('Memory...read')
        def write(self):
            print('Memory...write')
    
    class Network(File):
        def read(self):
            print('Network...read')
        def write(self):
            print('Network...write')
    # 鸭子类型的写法
    
    # 内存类
    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. 封装

    封装:从封装本身的意思去理解。封装就好像是拿来一个麻袋,把小猫,小狗,小王八,一起装进麻袋,然后把麻袋封上口子

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

    如何用代码实现隐藏

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

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

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

    隐藏属性是为了安全

    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.set_xx('6688')
    print(p.__dict__)
    
    # 计算人的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.height**2)
    
    p = Person('bob',1.81,68)
    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):
            # isinstance:判断对象是否是某个类的对象
            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('bob',1.81,68)
    # print(p.name)
    p.name='pppp'
    # p.name='xxx'
    #改不了,直接抛一异常
    # p.name=999
    # p.name='sb_nick'
    
    print(p.name)
    
    del p.name
    print(p.name)
    
  • 相关阅读:
    AS将一个项目导入到另一个项目中
    Android Studio出现:Cause: unable to find valid certification path to requested target
    小米手机Toast带app名称
    PopupWindow 点击外部区域无法关闭的问题
    EditText inputType类型整理
    Fragment通过接口回调向父Activity传值
    Android selector一些坑
    Installation failed with message Failed to commit install session 634765663 with command cmd package
    旷视上海研究院机器人方向招聘
    语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  • 原文地址:https://www.cnblogs.com/yushan1/p/11426449.html
Copyright © 2020-2023  润新知