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