面向对象编程简介

假如想象 提交于 2019-11-25 20:17:44

面向对象编程

一.什么是面向对象?

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)

为什么要用面向对象?

怎么用面向对象?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!