• 面向对象编程简介


    面向对象编程

    一.什么是面向对象?

    1 面向对象是一门编程思想

    面向对象编程思想:核心是“对象”二字,对象指的是“特征与技能”的结合体

    基于该编程思想编写程序,好比在创造世界,一种“上帝式”的思维方式

    优点:可扩展性高

    缺点:编写程序复杂度较高

    与面向过程编程思想的对比

    面向过程编程思想:核心是“过程”二字,过程指的是解决问题的步骤,即先干什么再干什么

    基于该编程思想写程序,就好比在设计一条工厂流水线,一种机械式的思维方式

    优点:将复杂的问题流程化,进而简单化

    缺点:牵一发而动全身,程序的可扩展性差

    注意: 编程思想仅仅是一门思想,与任何的技术无关。

    2 定义类的语法

    class(关键字) 类的名字 :

    #通过类名称空间的得到的字典取值
    class OldboyStudent:  #定义类,类名为OldboyStudent(类名使用驼峰体命名)
        school = 'oldboy' #定义相同的特征
        def learn(self):  #定义相同的技能,在类内部定义函数,会有一个默认参数self
            print('python真有趣...')
    
    
    print(OldboyStudent)
    print(OldboyStudent.__dict__)
    print(OldboyStudent.__dict__['school'])
    print(OldboyStudent.__dict__['learn'](1))
    #结果为
    <class '__main__.OldboyStudent'> #类的对象地址
    {'__module__': '__main__', 'school': 'oldboy', 'learn': <function OldboyStudent.learn at 0x000001A937F58B88>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None}  #类的名称空间
    oldboy          #取值
    python真有趣...  #得到函数体代码执行的结果,默认返回值为None
    None
    
    #类名.名字的取值方式
    查
    print(OldboyStudent.school)
    oldboy
    改
    OldboyStudent.school = 'OldGirl'
    print(OldboyStudent.school)
    OldGirl
    增
    OldboyStudent.old_student = 'boy'
    print(OldboyStudent.old_student)
    boy
    删
    del OldboyStudent.school
    print(OldboyStudent.school)
    报错
    
    

    PS:函数的名称空间:在调用函数时产生,函数调用结束后销毁。

    ​ 类的名称空间:在定义阶段时产生,会将类中所有的名字,扔进类的名称空间中。

    3 如何产生对象

    引入类的去产生对象

    在程序中必须先有类,再通过”调用类,产生对象“

    对象指的是”特征与技能“的结合体,类指的是一系列”对象之间向同的特征与技能“的结合体

    对象是把数据与功能整合到一起的产物,或者说”对象“就是一个盛放数据与功能的容器/箱子/盒子。

    #对象的产生,通过类名+()调用产生对象
    类的名称空间在定义时产生,对象的名称空间在调用类时产生
    调用类产生对象的过程称之为类的实例化,对象称之为类的一个实例
    
    class Student:
        school = 'oldboy'
        def learn(self):
            print(self)
            print('learning...')
    stu1 = Student()
    stu2 = Student()
    
    print(Student)
    print(Student.school)
    print(Student.learn(123))
    #结果为
    <class '__main__.Student'>
    oldboy
    123 #self相当一个形参,调用learn时将123传入
    learning...
    None
    
    print(stu1)
    print(stu1.learn()) #此处我们在调用learn函数时没有给其传入参数,是因为对象调用方法时会将对象当做第一个参数传入方法中,所以打印了两次对象地址
    print(stu1.school)
    #结果为
    <__main__.Student object at 0x0000019ABF207B08>
    <__main__.Student object at 0x0000019ABF207B08>
    learning...
    None
    oldboy
    
    print(stu2)
    print(stu2.learn())
    print(stu2.school)
    #结果为
    <__main__.Student object at 0x0000023613417788>
    <__main__.Student object at 0x0000023613417788>
    learning...
    None
    oldboy
    

    小结:

    1.不同的对象对应不同的内存地址

    2.对象在调用类内部的函数时,会将对象当作第一个参数传入

    #给对象添加新的属性
    class Student:
        school = 'oldboy'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            print(self.__dict__)  #查看对象的名称空间
        def learn(self):
            print(self)
            print('learning...')
    print(Student.__dict__)    #查看类的名称空间
    print(Student('sean', 72, 'male')) #将对应的参数传入
    #结果为
    '__module__': '__main__', 'school': 'oldboy', '__init__': <function Student.__init__ at 0x00000279C4434A68>, 'learn': <function Student.learn at 0x00000279C4434C18>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
    {'name': 'sean', 'age': 72, 'sex': 'male'}
    <__main__.Student object at 0x00000279C4468748>
    
    
    class Student:
        school = 'oldboy'
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
            print(self.__dict__)
        def learn(self):
            print(self)
            print('learning...')
    stu1 = Student('sean', 17, 'male')  #调用传入参数的类来产生对象
    stu2 = Student('tank', 18, 'male')
    print(stu1.name)  #通过对象.的方式来取值
    print(stu2.name)
    #结果为
    {'name': 'sean', 'age': 17, 'sex': 'male'}
    {'name': 'tank', 'age': 18, 'sex': 'male'}
    sean
    tank
    

    小结:

    1.凡是在类内部定义的,__开头或者__结尾的方法都有特殊的意义。

    2.在类内部定义的方法,在调用类时触发,会自动将对象本身当做第一个参数自动传入, 与括号内所有的参数一并传给__init__()。

    4.对象名字的查找顺序
    class People:
        country = 'China'
        name = 'Jason'
        def __int__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
        def run(self):
            print('keep running...')
    
    
    obj1 = People('tank', 17, 'male')
    print(obj1.name)
    print(obj1.country) #对象没有,找类中的属性
    print(obj1.jason) #类中也没有,则报错
    #结果为
    tank
    China
    AttributeError: 'People' object has no attribute 'jason'
        
    print(obj1.country)
    print(obj1.__dict__)
    obj1.country = '中国' #给对象添加country属性
    print(obj1.country)
    print(obj1.__dict__)
    #结果为
    China
    {'name': 'tank', 'age': 17, 'sex': 'male'}
    中国
    {'name': 'tank', 'age': 17, 'sex': 'male', 'country': '中国'}
    
    

    小结:

    对象名字的查找顺序:
    1.对象.属性,会先找对象自己的。
    2.若对象没有,会去找类的。
    3.若类没有,则会报错。

    #小项目:人狗大作战
    class People:
        def __init__(self, name, life, arg):
            self.name = name
            self.life = life
            self.arg = arg
        def bite(self, dog_obj):
            print(f'人:{self.name}开始咬狗:{dog_obj.name}')
            dog_obj.life -= self.arg
            print(f'狗的生命值减掉:{self.arg},狗的血量还剩{dog_obj.life}')
            if dog_obj.life <= 0:
                print(f'狗{dog_obj.name}已经挂了')
                return True
    
    class Dog:
        def __init__(self, name, life, dog_type, arg):
            self.name = name
            self.life = life
            self.dog_type = dog_type
            self.arg = arg
        def bite(self, p_obj):
            print(f'狗:{self.name}开始咬人:{p_obj.name}')
            p_obj.life -= self.arg
            print(f'人的生命值减掉:{self.arg},人的血量还剩{p_obj.life}')
            if p_obj.life <= 0:
                print(f'人{p_obj.name}已经挂了')
                return True
    
    p1 = People('卢锡安', 1500, 300)
    d1 = Dog('克格莫', 1000, '大嘴', 250)
    import time
    while True:
        res1 = d1.bite(p1)
        if res1:
            break
        time.sleep(1)
        res2 = p1.bite(d1)
        if res2:
            break
        time.sleep(1)
    
  • 相关阅读:
    如何透过上层div点击下层的元素解决方法
    学习javscript函数笔记(二)
    js栈内存和堆内存的区别
    学习javscript对象笔记(一)
    小程序 给最外层view设置百分之百高度不起作用
    小程序 开发阶段请求网络报 不在以下 request 合法域名列表中
    git安装以及webstorm配置git
    failed to push some refs to 'git@github.com:xxx/xxx.git' 解决方法
    Jquery EasyUI Treegrid按需加载子集
    js时间戳与日期格式的相互转换
  • 原文地址:https://www.cnblogs.com/a736659557/p/11929926.html
Copyright © 2020-2023  润新知