zoukankan      html  css  js  c++  java
  • Python-面向对象(组合、封装与多态)

    一、组合

    什么是组合?

    就是一个类的属性 的类型 是另一个自定义类的 类型,也可以说是某一个对象拥有一个属性,该属性的值是另一个类的对象。

    通过为某一个对象添加属性(这里的属性是另一个类的对象)的方式,间接将两个类关联整合,从而减少类与类之间的代码冗余

    class A:
        pass
    class B:
        pass
    b = B()
    b.a=A()

    借用之前的代码进行改进:

    class OldboyPeople:
        school = 'Oldboy'
    
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    class OldboyStudent(OldboyPeople):
        def __init__(self,name,age,sex,score=0):
            OldboyPeople.__init__(self,name,age,sex)
            self.score = score
            self.courses=[]
    
        def choose(self):
            print('%s choosing course' % self.name)
    
        def tell_all_course(self):
            print('学生[%s]选修的课程如下'%self.name)
            for obj in self.courses:
                obj.tell_info()
    
    class OldboyTeacher(OldboyPeople):
        def __init__(self,name,age,sex,level):
            OldboyPeople.__init__(self,name,age,sex)
            self.level = level
            self.courses = []
    
        def score(self,stu,num):
            stu.score = num
    
        def tell_all_course(self):
            print(('老师[%s]教授的课程如下'%self.name).center(50,'*'))
            for obj in self.courses:
                obj.tell_info()
            print('*'*60)
    
    
    class Coures:
        def __init__(self,c_name,c_price,c_period):
            self.c_name = c_name
            self.c_perice = c_price
            self.c_period = c_period
    
        def tell_info(self):
            print('<课程名:%s 价格:%s 周期:%s'%(self.c_name,self.c_perice,self.c_perice))
    
    
    stu = OldboyStudent('zfj',18,'male')
    teh = OldboyTeacher('egon',19,'femal',10)
    # print(stu.__dict__)
    python = Coures('python全栈开发','1900','5mons')
    linux = Coures('linux架构师','100','3mons')
    
    stu.courses.append(python)
    teh.courses.append(python)
    stu.tell_all_course()
    teh.tell_all_course()
    View Code

    二、多态

    多态指的是同一种类或者事物的不同形态

      多态性:在多态的背景下,可以在不用考虑对象具体类型的前提下直接使用对象

      多态性的精髓:统一

    人,狗,猪都是同属于动物的,他们都具有说和跑的特点,将共同的特点剥离出来组成父类

    import abc
    
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def speak(self):
            pass
    
        @abc.abstractmethod
        def run(self):
            pass
    
    # Animal() # 父类只是用来建立规范的,不能用来实例化的,更无需实现内部的方法
    
    class People(Animal):
        def speak(self):
            print('say hello')
    
        def run(self):
            pass
    
    class Dog(Animal):
        def speak(self):
            print('汪汪汪')
    
        def run(self):
            pass
    
    class Pig(Animal):
        def speak(self):
            print('哼哼哼')
    
        def run(self):
            pass
    
    obj1=People()
    obj2=Dog()
    obj3=Pig()

    这里涉及到了抽象类,我们导入了abc模块,abc.ABCMeta 是一个metaclass,用于在Python程序中创建抽象基类。

    在相应的方法之前一行加上@abstractmethod之后,从新的一行开始定义相应的方法。实现的方法就是一个抽象的方法,子类继承之后,如果需要用到的这个方法则必须用新的方法将其实现

    总结一句话就是,抽象类不能实例化,子类必须实现(抽象)父类的所有抽象方法

    Python崇尚鸭子类型:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

    在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的

    class Disk:
        def read(self):
            print('Disk read')
    
        def write(self):
            print('Disk write')
    
    
    class Memory:
        def read(self):
            print('Mem read')
    
        def write(self):
            print('Mem write')
    
    
    class Cpu:
        def read(self):
            print('Cpu read')
    
        def write(self):
            print('Cpu write')
    
    
    obj1=Disk()
    obj2=Memory()
    obj3=Cpu()
    
    obj1.read()
    obj2.read()
    obj3.read()
    View Code

    三、封装

    封:代表将存放于名称空间中的名字给藏起来,这种隐藏对外不对内

    装:往容器/名称空间里存放名字

    封装:将类的属性与方法私有化,形成对内可见对外不可见

    如何封装?

      在类内定义的属性前加_开头(没有_结尾)

    class Foo:
        # part1
        # __num = 1000
    
        # part2
        # def __init__(self, name):
        #     self.__name = name
    
        # part3
        def __test(self): # 变形成_Foo_test
            print("test")
    
    # part1
    # foo = Foo()
    # print(foo.__num)
    
    # part2
    # foo = Foo("*****")
    # print(foo.__name)
    
    foo = Foo()
    foo._Foo__test()
    View Code

    想要访问被私有化的属性,需要在要访问的对象前面加_类名。方法名

    注:

    1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问。

    2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形

    3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

    四、property

    property装饰器是用来将类内的函数属性伪装成数据属性的,里面有getter,setter、(deleter)方法

    class Car:
        def __init__(self, name, type):
            self.__name = name
            self.__type = type
        def __str__(self):
            return ">> " + self.__name + "" + self.__type + "】<<"
    
        # __name对外不可见,但外界需要访问,所以通过方法对外界间接性提供__name
        # 完成这类功能的方法称之为接口
        @property # name() => name
        def name(self):
            # 可以做一系列安全操作
            return self.__name
        # @name.getter
        # def name(self):
        #     return self.__name
    
        # @name.setter
        # def set_name(self, name):
        #    self.__name = name
        @name.setter
        def name(self, name):
           self.__name = name
    
    
    car = Car("宝马", "7系")
    # >> 宝马【7系】<<
    print(car)
    
    # 访问属性,带着()不够逼格
    # print(car.name())
    print(car.name)  # 取值:getter
    
    # car.set_name("奥迪")
    # car.set_name = "奥迪"  # 设置:setter
    car.name = "奥迪"
    print(car)
    View Code

    还要继续努力

  • 相关阅读:
    Python3——爬取淘宝评论
    python爬虫 URL分析
    python3爬取网页图片
    python_2 / python_3 区别与安装问题
    vue.$nextTick 解决了哪些问题
    Vue 路由缓存
    vue elementui form表单验证
    Hadoop Hive sql 语法详解
    sql server, mysql, oracle平时用法的区别
    Excel中值得收藏的12个函数公式
  • 原文地址:https://www.cnblogs.com/mangM/p/9513780.html
Copyright © 2011-2022 走看看