• 面向对象的总结


    一 、面向对象介绍

    編程——程序员通过一些列语法+数据结构+算法的集合,告诉计算机如何解决问题的过程。

    编程范式——对各种编程方法的总结,有两种:面向过程、面向对象。

     

    1.面向过程——把一个问题,分解成多个子问题或子过程,然后再把子过程进行分解,直到问题可以在一个小范围内解决。

         优:流程化,进而简单化

         缺:可扩展性低

         场景:一次性任务。

    2.面向对象——通过类和对象,来创建出各种模型来实现对象真实世界的描述。

         优:可扩展性高,

         缺:编程复杂度高。

         场景:网络编程。

     

    二、名词解析:

    1.类——具有相同属性的对象的抽象。

    2.属性——一类事物的特征。

    3.方法——一类事物的技能。

    4.实例(对象)——一个类的实例化后实例

    5.实例化——一个类实例或成对象的过程。

    6. 总结:对象的抽象是类,类的具体化就是对象;也可以说类的实例化是对象,对象是类的实例。

    例子代码如下:

    # -*- encoding:utf-8 -*-
    class MyName:  #创建类,Myname为类名
        a=88 #类的一个属性
        def approach1(love): #方法1
            pass#方法一的作用
        def approach2(love): #方法2
            pass#方法二的作用
    

      

    三、面向对象的三大特征:

    1.封装

    (1)对类的数据的赋值、内部调用对外部的用户都是透明的,这使得类成为一个容器,里面包含着类的数据和方法。

        封装的注意事项

           1. 封装后切记不要直接访问对象的属性

      2.封装后存在的问题和解决方案

    误区1:什么样的属性应该封装?封装的话是不是一定要添加限制访问条件?

                   (1) 为了让定义的数据类型,能使用不同的应用场景,一帮情况下我们要对当前类型的所有属性进行封装处理。

                   (2) 封装属性之后,会提供访问属性数据的set/get方法,开发过程中方法中不需要添加任何限制条件,只是预留了可以添加限制条件的方法而已,后期根据项目需求进行限制条件的完善

     

    误区2:私有属性,完全不能直接访问

        我们定义了私有属性,就是两个下划线开头的属性

        理论上外界不能直接访问,而是要通过我们提供的set/get方法间接访问

       

        功能开发过程中,代码和功能都可能会存在一些问题

            如果发现问题~一定要及时沟通,而不是私自修改。

     

    (2) 调用封装的内容有2种方法:

    ——通过对象直接调用

    ——通过self间接调用

    例子代码如下:

    # -*- encoding:utf-8 -*-
    ''' 实例说明——面向对象的特征:封装 '''
    
    class Student:
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def detail(self): #调用时对象名会传给self参数,如最后一句
            print(self.name)
            print(self.age)
    
    obj1 = Student('Jack',15)  #将'Jack'和15分别封装到obj1的self的name和age属性中
    print(obj1.name)  #通过对象直接调用name属性和age属性
    print(obj1.age)
    
    obj2 = Student('Sahra',13) #将'Sahra'和13分别封装到obj2的self的name和age属性中
    obj2.detail()     #通过self间接调用name属性和age属性

     

    2.继承

    一个类可以派生出子类,这个父类的属性、方法自动被子类继承。

    注:Python的类可以继承多个类,而Java和C#中则只能继承一个类

    Python的类如果继承了多个类,那么其寻找方法的方式有2种:

     

    • 当类为经典类时会按照深度优先方式查找

    • 当类为新式类时会按照广度优先方式查找

     

    继承的实例:

     

    # -*- encoding:utf-8 -*-
    ''' 实例说明——面向对象的特征:继承 '''
    
    class Person(object):   #定义Person父类
        def talk(self):       #定义父类的方法
            print("Person can talk.")
    class Chinese(Person):  #定义Person父类的一个子类,同时是Characters类的父类
        def talkC(Person):    #定义方法
            print("Chinese can talk Mandarin.")
    class Characters(Chinese):  #定义Chinese父类的一个子类
        def people(self):         #定义方法
            print("Chinese are clever and diligent.")
    class American(Person):   #定义Person父类的一个子类
        def talkA(self):       #定义方法
            print("American can talk English.")
    
    C = Characters() #定义父类的子类的子类
    A = American()   #定义父类的子类
    C.talk()         #调用继承Person类的方法
    A.talkA()        #调用本身的方法
    C.people()       #调用本身的方法

     

    3.多态

    一个接口、多种实现。一个父类派生出不同的子类,且每个子类在继承父类的方法的同时,又对父类的方法做了不同的实现,这就是同一种事物表现出多种形态。

     例子代码如下:

    # -*- encoding:utf-8 -*-
    ''' 实例说明——面向对象的特征:多态 '''
    import abc
    
    class Animal(metaclass=abc.ABCMeta): #同一类事物:动物
    
        @abc.abstractmethod
        def talk(self):
            pass
    
    class People(Animal): #动物的形态之一:人
        def talk(self):
            print('say hello')
    
    class Dog(Animal):    #动物的形态之二:狗
        def talk(self):
            print('say wangwang')
    
    class Pig(Animal):    #动物的形态之三:猪
        def talk(self):
            print('say aoao')
    
    
    peo = People() #创建People类的对象peo
    dog = Dog()    #创建Dog类的对象dog
    pig = Pig()    #创建Pig类的对象pig
    peo.talk()     #分别使用各种的方法
    dog.talk()
    pig.talk()

     

    四类与对象

    1.构造方法(__init__)

            实例化时给实例一些初始化的参数。

    2.普通方法==函数

    3.析构方法(__del__)

        删除实例化后的对象

     

    五、类与对象的概念

    1.现——先有对象后又类

    2.程——先定义类 后产生对象

     

    注意

    1、    类中的代码,定义阶段便会执行,产生新的名称空间存放。可以通过(__dict__)查看

    2、    类定义的名字,是类的属性,点是访问属性的方法。

    3、    我们可以通过操作字典的方法获得类的值。

     

    六、对象的使用

    1、    站的角度不同,定义的类是不同

    2、    现实的类并不完全等于程序中的类

    3、    程序中可能定义不存在的类。

    七、类的成员

    1. 简介:类的成员包括字段、方法和属性。在所有成员中,只有字段中的普通字段保存于对象中,因此创建多少个对象在内存中就有几个普通字段;而其他成员都保存在类中,也只占用一份内存空间。

    2. 字段:包括普通字段和静态字段,他们在定义和使用都有所区别,而最本质的区别是内存中保存的位置不同。

    (1) 普通字段保存在对象中

    (2) 静态字段保存在类中

     

     

    3. 方法:包括普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

    (1) 公有方法

    调用:可由对象名直接调用;如果通过类名来调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的数据成员。

    特点:至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self。在此方法中可以访问属于类和对象的成员。

    (2) 私有方法

    调用:只能在属于对象的方法中通过self调用或在外部通过Python支持的特殊方式来调用。在此方法中可以访问属于类和对象的成员。

    (3) 静态方法

    调用:可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。

    特点:无默认参数。

    (4) 类方法

    调用:可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。

    特点:至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls。

     

    八、属性查找与绑定方法

    1.属性查找

    两种属性:数据属性、函数属性。

    类中数据属性——所有对象共享的。

    类中函数属性——绑定给对象用的,称绑定到对象的方法。

    查找:对象名称空间》类》父类》最后抛出异常

     

    2.绑定方法

    1、类的函数属性是绑定给对象使用的,绑定到不同的对象就是不同的绑定方法。

    2、类中定义的函数,类可以调用,按函数调用规则。有几个参数传几个参数。

    3、绑定到对象那个的方法这种自动传值的特征,决定了类在定义函数都要默认写一个self。

     

    3.类即类型

    Python中一切皆对象,py3中,类与类型是一个概念。

     

     

    4.继承与派生

    继承——类与类间的关系,是一种什么是什么的关系。

    新建的类可以继承一个或多个父类,父类可以成为基类或超类。新建的类称为派生或子类。

     

    5.继承与抽象

    先抽象、后继承。

     

    6.继承与重用

    通过继承的方式新建类,可以有父类的属性,实现代码重用。

     

    7.继承与派生

    子类继承父类的属性,可以重新定义所继承的属性,也可以添加自己新的属性,一旦自己的属性与父类的属性重名,调用时以自己为准。

     

    8.继承实现原理

    定义类的时候Python自动生成一个MRO列表。

    查找顺序:

    1、    子类优先于父类。

    2、    多个父类会按顺序查找。

    3、    如果存在两个选择,优先选第一个父类。

    注意:新式类——广度优先;经典类——深度优先

     

    九、子类调用父类的方法

    1、    指名道姓调——普通类调用方式,与继承无关。

    2、    Super()——依赖继承、即使没有直接继承关系,也会按MRO继续往后查找。

     

    1.组合

    组合——一个类中以另一个类的对象作为数据属性。

            继承(什么【是】什么的关系)

            组合(什么【有】什么的关系)

     

    2.接口

    接口——提供给使用者调自己功能的方法。

    1、    提取了类的共同函数,把接口当做一个函数的集合。

    2、    让子类实现接口中的函数功能。

    接口的好处:使用者不需要关心对象的类是什么,只需要知道对象都有哪些功能就可以,降低使用难度。

     

     

    3.抽象类

    从一堆类中抽取相同的内容,内容包括数据和函数属性,抽象类只能继承不能实例化,子类必须实现抽象方法。(@abc.abstractmethod)  

     

    4.多态与多态性

    多态——一类事物有多种形态。

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

    分类:动态多态性,静态多态性。

    静态多态性:任何类型都可以用【+】进行运算。

    多态性的好处:1、增加程序灵活性

                  2、增加程序扩展性

     

    5.封装

    隐藏(通过__x的方式将属性隐藏起来(设置私有的))

    特点:

    1、   在类外部无法直接obj.__AttrName

    2、   在类内部是可以直接使用:obj._AttrName

    3、   子类无法覆盖父类__开头的属性

    注意的问题:

    1、   这种异常没有真正意义上的隐藏

    2、   这种变形在类定义阶段发生,定以后的赋值不会发生变形。

    3、   如果不想让子类覆盖自己的方法,可以将方法定义私有。

     

    封装的意义:

    1、   封装数据——明确区分内外,对外提供操作的接口和操作权限。

    2、   封装方法——隔离复杂度。用户只需通过简单的接口调用就可完成一系列操作。

     

    封装与扩展性

    封装在于明确区分内外,还使得类实现者可以修改封装内的东西而不影响外部调用者的代码。

     

    特性(propert)

        是一种特殊的属性,访问时会执行一段功能(函数)然后返回值。

         @Property、@setter、@deleter

    为什么要用特性?

         将一个类的函数定义成特性后,对象使用的时候,使用者无法察觉自己的调用方式,这种方式遵循了统一访问额原则。

    绑定方法与非绑定方法

    在类内部定义的函数分两大类

    1、    绑定方法(绑定给谁,就由谁来调用(把谁,作第一个参数传入))

    a)    绑定到类的方法:在类内部定义的,用classmethod装饰器装饰)

    b)    绑定到对象的方法:类内部定义,没有加任何装饰器。

    2、    非绑定方法:(用staticmethod装饰器装饰)

    不与类与对象绑定,类和对象都可以调用,但没有自动传值一说。

    二、python中以下划线开头的变量名特点:

    三、

    1. 三维向量类

    (1) 简述:实现向量的加减法、向量与标量的乘除法。

    (2) 代码实现:

    #  --coding: gb2312--
    ''' 三维向量 '''
    
    class vector3:
        def __init__(self, x_ = 0, y_ = 0, z_ = 0): #构造函数
            self.x = x_
            self.y = y_
            self.z = z_
    
        def __add__(self, obj):      #重载+作为加号
            return vector3(self.x+obj.x, self.y+obj.y, self.z+obj.z)
    
        def __sub__(self, obj):      #重载-作为减号
            return vector3(self.x-obj.x, self.y-obj.y, self.z-obj.z)
    
        def __mul__(self,n):         #重载*作为点乘
            return vector3(self.x*n, self.y*n, self.z*n)
    
        def __truediv__(self, obj):  #重载/作为除法
            return vector3(self.x/n, self.y/n, self.z/n)
    
        def __str__(self):
            return str(self.x)+','+str(self.y)+','+str(self.z)
    
    if __name__ == "__main__":
        n = int(input("请输入一个标量:"))
        a,b,c = map(int,input("请输入第一个向量:").split())
        v1 = vector3(a,b,c)
        a,b,c = map(int,input("请输入第二个向量:").split())
        v2 = vector3(a,b,c)
        print("两向量的加法:",v1 + v2)
        print("两向量的减法:",v1 - v2)
        print("标量与向量的乘法:",v1 * n)
        print("标量与向量的除法:",v1 / n)

    2. 英文字符串处理

     (1) 简述:用户输入一段英文,得到这段英文中所以长度为3的单词,并去除重复的单词。

     (2) 代码实现:

    方法一:

    # -*- encoding:utf-8 -*-
    ''' 将一段英文中长度为3的单词输出,并去掉重复的单词 '''
    
    import re
    import jieba
    class ProString:
        Str = ""
        Dict = {}
        Ls = []
        def __init__(self,string,length = 3): #初始化
            self.string = string
            self.length = length
            
        def SignalWord(self):        #去除重复的单词
            self.words = jieba.lcut(self.string)   #jieba分词
            for _ in self.words:                   #与词频算法相似
                self.Dict[_] = self.Dict.get(_,0) + 1
            del(self.Dict[' '])                 #删除空格项
            self.Ls = list(self.Dict.keys())    #字典类型转化成列表类型
            self.StubbenWord(self.Ls)
    
        def StubbenWord(self,Ls):       #利用去除重复的单词,得到固定长度的单词
            for _ in Ls:
                if len(_) == self.length:
                    self.Str += _ + ' '
            self.printf(self.Str)
            
        def printf(self,Str):
            print("处理后的字符串为:",Str)
                
    if __name__ == "__main__":
        str = input("请输入字符串:")
        process = ProString(str,3)
        process.SignalWord()

    方法二、

    # -*- encoding:utf-8 -*-
    ''' 将一段英文中长度为3的单词输出,并去掉重复的单词 '''
    
    import re
    class ProStr:
        a = []
        def __init__(self, words, length = 3):
            self.words = words
            self.length = length
    
        def process(self):
            word_list = re.split('[. ]+',self.words)
            for _ in word_list:
                if len(_) == self.length:
                    if _ not in self.a:
                        self.a.append(_)
                else:
                    continue
            self.printf()
    
        def printf(self):
            print("处理后的字符串为:", end = '')
            for _ in range(len(self.a)):
                print(self.a[_],end=' ')
    
    if __name__ == "__main__":
        words = input("请输入字符串:")
        process = ProStr(words, 3)
        process.process()
  • 相关阅读:
    装饰器模式
    观察者模式
    策略模式
    分析法汇总
    事后诸葛亮分析(名字好难想队)
    团队项目第六周——Alpha阶段项目复审(名字很难想队)
    团队博客(第五周)-“名字好难想”
    团队博客(第四周)-“名字好难想”
    团队博客(第三周)-“名字好难想”
    团队博客(第二周)-“名字好难想”
  • 原文地址:https://www.cnblogs.com/sgy614092725/p/shiguiyu7.html
Copyright © 2020-2023  润新知