zoukankan      html  css  js  c++  java
  • python--面向对象

    面向过程与面向对象

    面向过程的程序设计                                                                                                                                                         

    过程是核心,将复杂的变成流程化,处理起来比较简单。

    优点:将复杂的变成流程化,处理起来比较简单。

    缺点:扩展性差,修改起来非常困难

    应用场景: 一旦完成就很少改变的场景,例如 linux内核,git, 以及Apache HTTP Sever等。

    面向对象的程序设计                                                                                                                                                                                                                                                                                                                               

    对象是核心,对象是特征和技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是上帝,存在的一切皆为对象,不存在的也可以创造,与面向过程相比更加注重对现实世界的模拟,是一种“上帝式”的思维方式。

    优点:可扩展性强

    当然,一个程序的质量不仅仅是可扩展性,面向对象只是用来解决可扩展性。

    缺点:

    1.处理问题比较复杂,不了解面向对象而立即上手基于他设计程序,极容易出现过度设计的问题,对于一些扩展性要求较低的场景使用会增加编程难度。

    2.面向对象程序一旦开始就由对象之间的交互解决问题,无法预测问题处理的流程与结果,应用场景:需要经常变化的软件,一般集中在用户层,互联网应用,企业内部软件,游戏等

    类与对象

    类与对象的概念                                                                                                                                                                                                                                      

    类 即类别,种类是面向随想设计的最重要的概念,对象是特征和技能的结合体,类则是一系列对象相似的特征与技能的结合体。

    那么到底是现有对象在有类还是现有类才有的对象?

    在现实生活中肯定是现有的各种各样实际存在的对象,然后人们根据站在不同的角度总结出了不同的类,如人类,动物类,植物类,也就是说,对象是真是存在的,而类只是一个概念,并不存在。

    在程序中,先定义类,然后生成对象,与函数一样,都要先定义再调用,不同的是,调用函数返回的是函数执行的结果,调用类返回的是对象。

    定义类:

    在程序中,务必保证:先定义(类),后使用(产生对象)
    在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是”类“,对象则是这一类事物中具体的一个。

    class Student:                          # 定义一个学生类
        school = "luffy_city"              # 这里定义一个学生的属性,他们的学校都是luffy_city
        def __init__(self, name, sex, age):    # __init__ 方法可以定义一些属性相同但值不相同的属性
            self.name = name
            self.sex = sex
            self.age = age
        def learn(self):                       # 定义一个学习的技能
            return "%s is learnning" % self.name
        def eat(self):                          # 定义一个吃饭的技能
            return"%s is eatting" % self.name
        def sleep(self):                        # 定义一个睡觉的技能
            return "%s is sleeping" % self.name
    
    print(Student.__dict__)      # 可以通过   类名.__dict__拿到类中所有属性
    print(Student.school)       # 通过 类名.属性名 查看属性

    实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征。
    实例化的过程就是通过类产生对象的过程,在这个过程中,产生了一个具有具体的名字,性别,年龄和技能的对象。
    语法:对象名 = 类名(参数)
    student1 = Student("李二蛋", "man", 25) # 类名()相当于调用__init__方法,会自动将对象名当作第一个参数传给self ,相当于Student.__init__("student1","李二蛋", "man", 25)
    查看属性和调用方法
    print(student1.name)
    print(student1.learn()) # 会自动将对象名当作参数传给self,相当于Student.learn("student1")

    类属性的补充:

    一、我们定义的类到底保存在哪里了?查看方式dir(类名):查出的是一个名字列表类名.__dict__:查出的是一个字典,key为属性名,value为属性值

    二、特殊的类属性类名.__name__ 类的名字(字符串)类名.__doc__ 类的文档字符串类名.__base__ 类的第一个父类类名.__bases__ 类的所有父类类名.__dict__ 类的字典属性类名.__module__类定义所在的模块类名.__class__ 实例对应类

    类属性的操作                                                                                                                                               
    Student.school #
    Student.school='Oldboy' #
    Student.x=1 #
    del Student.x #
    对象属性的操作                                                                                                                                            
    # 调用类,或称为实例化,得到程序中的对象,执行类中的__init__方法,也会产生对象的名称空间可以用student_1.__dict__查看,查看结果为{'name': '李二蛋', 'sex': 'man', 'age': 25}
    student_1.name
    #查,等同于student_1.__dict__['name'] student_1.name='王三炮' #改,等同于student_1.__dict__['name']='王三炮' student_1.course='python' #增,等同于student_1.__dict__['course']='python' del student_1.course #删,等同于student_1.__dict__.pop('course')
    
    

     属性查找及绑定方法                                                                                                                                         

    属性查找

    类有两种属性:数据属性和函数属性

    1、类的数据属性是所有对象共享的

    #类的数据属性是所有对象共享的,id都一样
    print(id(student_1.school))
    # 1531561867504
    print(id(student_2.school))
    # 1531561867504
    print(id(student_3.school))
    # 1531561867504

    2、类的函数数据是绑定给对象用的,称为绑定到对象的方法

    #类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
    print(Student.learn)
    # <function Student.learn at 0x00000164983D9730>
    print(student_1.learn)
    # <bound method Student.learn of <__main__.Student object at 0x00000164983D6F28>>
    print(student_2.learn)
    # <bound method Student.learn of <__main__.Student object at 0x00000164983D6F60>>
    print(student_3.learn)
    # <bound method Student.learn of <__main__.Student object at 0x00000164983D6F98>>

    绑定方法

    类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数,其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法。

     强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)

    print(Student.learn(student_1))
    # 李二蛋 is learnning
    print(student_1.learn())
    # 李二蛋 is learnning

    注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。

    类即类型

    python中一切皆为对象,且python3中类与类型是一个概念,类型就是类

    #类型dict就是类dict
    >>> list
    <class 'list'>
    
    #实例化的到3个对象l1,l2,l3
    >>> l1=list()
    >>> l2=list()
    >>> l3=list()
    
    #三个对象都有绑定方法append,是相同的功能,但内存地址不同
    >>> l1.append
    <built-in method append of list object at 0x10b482b48>
    >>> l2.append
    <built-in method append of list object at 0x10b482b88>
    >>> l3.append
    <built-in method append of list object at 0x10b482bc8>
    
    #操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3
    >>> l1.append(3)
    >>> l1
    [3]
    >>> l2
    []
    >>> l3
    []
    #调用类list.append(l3,111)等同于l3.append(111)
    >>> list.append(l3,111) #l3.append(111)
    >>> l3
    [111]

    小练习:实现对象之间的交互

    class Hero:                  # 定义一个英雄的类
        role = "hero"            # 定义一个公同属性角色
    
        def __init__(self, life_value, aggressivity, defensive):     # 定义一个自定义值的属性函数 属性包括生命值,攻击力,防御
            self.life_value = life_value
            self.aggressivity = aggressivity
            self.defensive = defensive
    
        def attack(self, target):
            target.life_value -= (self.aggressivity - target.defensive)    # 定义一个攻击技能
    
    
    garen = Hero(100, 60, 30)                             # 实例化一个盖伦对象,并传入英雄的生命值,攻击,防御
    rivan = Hero(90, 70, 20)                              # 实例化一个锐雯对象,并传入英雄的生命值,攻击力,防御
    garen.attack(rivan)                                         # 盖伦攻击瑞文一次
    rivan.attack(garen)                                         # 瑞文攻击盖伦一次
    print(garen.life_value)                                     # 打印盖伦的生命值 60
    print(rivan.life_value)                                     # 打印瑞文的生命值 50
  • 相关阅读:
    gain 基尼系数
    luogu P5826 【模板】子序列自动机 主席树 vector 二分
    牛客挑战赛39 树与异或 离线 树上莫队 树状数组 约数
    4.22 省选模拟赛 三元组 manacher 回文自动机
    4.22 省选模拟赛 最优价值 网络流 最大权闭合子图
    4.18 省选模拟赛 消息传递 树剖 倍增 线段树维护等比数列
    luogu P4008 [NOI2003]文本编辑器 splay 块状链表
    牛客挑战赛39 密码系统 后缀数组
    luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝
    luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
  • 原文地址:https://www.cnblogs.com/zt0903/p/10828715.html
Copyright © 2011-2022 走看看