zoukankan      html  css  js  c++  java
  • 面向对象编程(二)

    类与对象的概念

    类即类别、种类,是面向对象设计最重要的概念,从一小节我们得知对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体。

    那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看

    • 在现实世界中:肯定是先有对象,再有类
    世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,比如
    人类、动物类、植物类等概念。也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在,比如你无法告诉我人类
    具体指的是哪一个人。
    
    • 在程序中:务必保证先定义类,后产生对象
    这与函数的使用是类似的:先定义函数,后调用函数,类也是一样的:在程序中需要先定义类,后调用类。不一样的是:调用
    函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象
    

    定义类

    按照上述步骤,我们来定义一个类

    • 在现实世界中,先有对象,再有类
    class OldboyStudent:
        school='oldboy'
        def learn(self):
            print('is learning')
    
        def eat(self):
            print('is eating')
    
        def sleep(self):
            print('is sleeping')
    View Code

    注意:

    • 类中可以有任意python代码,这些代码在类定义阶段便会执行,因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过OldboyStudent.__dict__查看
    • 类中定义的名字,都是类的属性,点是访问属性的语法。
    • 对于经典类来说我们可以通过该字典操作类名称空间的名字,但新式类有限制

    类的使用

    • 引用类的属性
      OldboyStudent.school #
      OldboyStudent.school='Oldboy' #
      OldboyStudent.x=1 #
      del OldboyStudent.x #
      View Code
    • 调用类,或称为实例化,得到程序中的对象
      s1=OldboyStudent()
      s2=OldboyStudent()
      s3=OldboyStudent()
      
      #如此,s1、s2、s3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__
      View Code
    • __init__方法
      #注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值
      class OldboyStudent:
          ......
          def __init__(self,name,age,sex):
              self.name=name
              self.age=age
              self.sex=sex
          ......
      
      s1=OldboyStudent('李坦克','',18) #先调用类产生空对象s1,然后调用OldboyStudent.__init__(s1,'李坦克','男',18)
      s2=OldboyStudent('王大炮','',38)
      s3=OldboyStudent('牛榴弹','',78)

    对象的使用

    #执行__init__,s1.name='牛榴弹',很明显也会产生对象的名称空间可以用s2.__dict__查看,查看结果为
    {'name': '王大炮', 'age': '', 'sex': 38}
    
    s2.name #查,等同于s2.__dict__['name']
    s2.name='王三炮' #改,等同于s2.__dict__['name']='王三炮'
    s2.course='python' #增,等同于s2.__dict__['course']='python'
    del s2.course #删,等同于s2.__dict__.pop('course')
    View Code

    补充说明

    • 站的角度不同,定义出的类是截然不同的;
    • 现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类等;
    • 有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类。

    属性查找

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

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

    #类的数据属性是所有对象共享的,id都一样
    print(id(OldboyStudent.school))
    
    print(id(s1.school)) #4377347328
    print(id(s2.school)) #4377347328
    print(id(s3.school)) #4377347328
    

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

    类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
    
    print(OldboyStudent.learn) #<function OldboyStudent.learn at 0x1021329d8>
    print(s1.learn) #<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>>
    print(s2.learn) #<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>>
    print(s3.learn) #<bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>
    
    #ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
    

    在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常

    绑定方法

    定义类并实例化出三个对象

    class OldboyStudent:
        school='oldboy'
        def __init__(self,name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def learn(self):
            print('%s is learning' %self.name) #新增self.name
    
        def eat(self):
            print('%s is eating' %self.name)
    
        def sleep(self):
            print('%s is sleeping' %self.name)
    
    
    s1=OldboyStudent('李坦克','男',18)
    s2=OldboyStudent('王大炮','女',38)
    s3=OldboyStudent('牛榴弹','男',78)
    

    类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数

    OldboyStudent.learn(s1) #李坦克 is learning
    OldboyStudent.learn(s2) #王大炮 is learning
    OldboyStudent.learn(s3) #牛榴弹 is learning

    类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法、

    类即类型

    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]
    

      

  • 相关阅读:
    java线程的理解
    linux常用命令
    排序算法-(2)-选择排序
    git查看某个文件修改历史
    Information:java: javacTask: 源发行版 1.8 需要目标发行版 1.8
    排序算法-(1)-插入排序
    去重脚本
    771.宝石与石头
    json 的应用
    xml 文件处理
  • 原文地址:https://www.cnblogs.com/leesen934/p/9080924.html
Copyright © 2011-2022 走看看