面向对象编程
一.什么是面向对象?
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)