面向对象
1.什么是面向对象?
面向对象时一门编程思想!
-面向过程编程思想:
核心是‘过程’二字,过程指的是解决问题的步骤,即先干什么,再干什么!
基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式。
优点:将复杂的问题流程化,进而简单化
缺点:牵一发而动全身,程序的可扩展性差
注:编程思想仅是一门思想,与任何的技术无关
-面向对象编程思想:
注意:要将自己当做一个上帝!
核心是‘对象’二字,对象指的是‘特征与技能’的结合体
基于编程思想写程序,就好比创造世界,一种‘上帝式’的思维方式
优点:
可扩展性高
缺点:
编写程序的复杂程度比面向过程高
2、如何产生对象:
1)什么是类?
类指的是类型、类别
-在两种角度去看待:
-在现实世界中:
-先有一个个的对象,经过社会的文明发展,随之总结出来
对象时实际存在的,而类抽象产生的
-在程序中:
-必须先有类,再通过‘调用类,产生对象’
对象指的是‘特征与技能’的结合体,类指的是一系列‘对象之间相同的特征与技能’的结合体。
2)如何定义类:
-如何写类并产生对象:
-先从现实世界中通过一个个对象总结出来
-然后再定义类,后调用类产生对象
比如: 选课系统:
- 选课系统学生类:
- 学生对象1:
特征:
- 姓名: hcy
- 性别: female
- 年龄: 95
- 学校: oldboy
- 技能:
- 技术: python
- 学习: learn
- 选课: course
- 学生对象2:
特征:
- 姓名: gaodi
- 性别: female
- 年龄: 98
- 学校: oldboy
- 技能:
- 技能:
- 技术: python
- 学习: learn
- 选课: course
3)定义类语法:
class 关键字:帮你产生类的
class 类的名字:
-对象之间相同的特征
-学校
school = ‘old boy’
-对像之间相同的技能
-python
def python():
pass
-learn
def learn():
pass
-course
def course():
pass
class 类名:
特征
技能
定义类名的规范:
-驼峰命名法
def foo(): #函数名指向的是函数的内存地址 pass print(foo) #<function foo at 0x10528b8b0>
#定义学生类
class OldboyStudet: #类名指向的是类的内存地址 #学生相同的特征 #在类中的特征 也称为之为"属性"attribute school = 'oldbay' #学生相同的技能 #注意:在类内部定义函数,会默认有一个参数self def learn(self): #self 此时当做一个形参 print('learn...') print(OldboyStudet)
查看类的名称空间
# 查看类的名称空间 print(OldboyStudent.__dict__) #{'__module__': '__main__', 'school': 'oldbay', # 'learn': <function OldboyStudent.learn at 0x109319820>, # '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, # '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None} print(OldboyStudent.__dict__['school']) #oldbay print(OldboyStudent.__dict__['learn']) #<function OldboyStudent.learn at 0x109319820> OldboyStudent.__dict__['learn'](123) #learn... 注:123是仅是一个参数(替换了原self)
类提供一种特殊取名字的方式,‘类名.名字’的方式
# 查 print(OldboyStudent.school) # oldbay OldboyStudent.learn('tank') # learn... #改 OldboyStudent.school = 'OldGirl' print(OldboyStudent.school) #OldGirl #删 del OldboyStudent.school # print(OldboyStudent.school) #type object 'OldboyStudent' has no attribute 'school' #增 OldboyStudent.school = 'Oldboy' print(OldboyStudent.school) # Oldboy OldboyStudent.Old_student = 'haha' print(OldboyStudent.Old_student) #haha
-函数的名称空间:
在调用函数是产生,函数调用结束后销毁
-类的名称空间:
在定义阶段时产生,会将类中所有的名字,扔进类的名称空间中。
对象的产生:
-调用类产生对象
类名 +()调用类产生对象
类的名称空间在定义时产生,对象的名称空间在调用类时产生
调用类产生对象的过程称之为类的实例化,对像称之为类的一个实例。
class Student: school = 'oldboy' #学习技能 --->method ---->方法 def learn(self): print(self) print('learning...')
stu1 = Student() stu2 = Student() stu3 = Student() # print(stu1) #<__main__.Student object at 0x10145c6d0> # # print(stu1.school,'stu1---') #oldboy stu1--- # # print(stu1.learn,'stu1####') #<bound method Student.learn of <__main__.Student object at 0x10b8b96d0>> stu1#### # # #对象调用方法时:会将对象当做一个参数传入方法中 # stu1.learn() #<__main__.Student object at 0x10bcd06d0> # #learning... # print(stu2) #<__main__.Student object at 0x10e4fedf0> # print(stu2.school,'stu2---') print(stu2.learn,'stu2...') #<bound method Student.learn of <__main__.Student object at 0x10695edf0>> stu2... # print(stu2.learn(),'stu2...') stu2.learn() #<__main__.Student object at 0x10ceb6df0> #learning...
由对象来调用类内部的函数,称之为对象的绑定方法
对象的绑定方法特殊之处:会将对象当做第一个参数传给该方法。
调用类产生对象发生的事情:
1、会产生一个空对象的名称空间
2、会自动触发__init__,并且会将对象当做第一个参数传入
3、会将调用类括号内的参数一并传给__init__()
class Student: school = 'oldboy' def __init__(self, name, sex, age): #stu1, 'tank', 'male', 17 print(self.__dict__) #给对象添加新的属性 self.name = name #stu1.x = 'tank' self.sex = sex #stu1.y = 'male' self.age = age #stu1.z = 17 #查看当前对象的名称空间 print(self.__dict__) #学习技能 ---->method ---->方法 def learn(self): print(self) print('learn...') #查看类的名称空间 # print(Student.__dict__) stu1 = Student('kangheng', 'female', 18) # stu2 = Student() # stu3 = Student() # print(stu1) #<__main__.Student object at 0x109f706d0> # print(stu2) #<__main__.Student object at 0x109f84df0> # print(stu3) #<__main__.Student object at 0x109f9bc10> stu1.name = 'kangheng' stu1.sex = 'female' stu1.age = 84 print(stu1.name, stu1.sex, stu1.age) print(stu1) #<__main__.Student object at 0x1014546d0># '''
总结:
class People: country = 'China' def __init__(self, name, age, sex): print(self.__dict__) print(self) self.name = name self.age = age self.sex = sex print(self.__dict__) # 注意: 看到self就应该知道是对象本身 def learn(self): print('learning....') p_obj = People('tank', 17, 'male') print(p_obj.name, p_obj.age, p_obj.sex) # 2.查看类与对象的名称空间 类.__dict__ 对象.__dict__ print(People.__dict__) print(p_obj.__dict__) # 3.类或对象的属性操作: 查、增、改、删 print(People.country) People.number = 1500 print(People.number) People.country = '中国' print(People.country) # del People.country # print(People.country) # print(p_obj.name) # p_obj.sal = 150000000 # print(p_obj.sal) # p_obj.age = 16 # print(p_obj.age) # del p_obj.sal # print(p_obj.sal) # 4.类中数据属性(类中的变量): 类中属性是给对象使用的,对象引用类中的属性,指向的都是类中同一个内存地址。 # p_obj1 = People('tank', 17, 'male') # p_obj2 = People('jason', 71, 'female') # p_obj3 = People('大饼', 72, 'female') # print(p_obj1.country, id(p_obj1.country)) # print(p_obj2.country, id(p_obj2.country)) # print(p_obj3.country, id(p_obj3.country)) # 5.类中的方法(类中的函数): 类中的方法是给对象使用的, # 由不同的对象来调用就会将方法绑定给不同的对象, 并且会将对象当做第一个参数传入。 # print(People.learn) # print(p_obj1.learn) # bound method # print(p_obj2.learn) # print(p_obj3.learn) # 6.对象属性的查找顺序: 先从对象自己名称空间中查找 ---》 类的名称空间中查找 # print(p_obj1.country) # print(p_obj1.country2) # 7.对象绑定方法的特殊之处: ''' 1.会将对象当做第一个参数传入。****** 2.若对象的绑定方法中还有其他参数,会一并传入。 ''' # p_obj1对象.对象的绑定方法learn(p_obj1): # p_obj1.learn() # 8.一切皆对象: 在python3中,类即类型。 # print(type(p_obj1)) # <class '__main__.People'> # str1 = 'tank' # print(type(str1)) # <class 'str'> # # list1 = [1, 2, 3] # print(type(list1)) # <class 'list'>
实例:人狗大战
''' 需求: 有一个人对象,狗对象,人狗互咬。 - 对象人1: - 特征: - 生命 - 名字: name = 'gaodi' - 攻击力: arg - 技能: - 咬:bite - 对象人2: - 特征: - 生命 - 名字: name = 'kangheng' - 攻击力: arg - 技能: - 咬:bite - 对象人3: - 特征: - 生命 - 名字: name = 'wangyagn' - 攻击力: arg - 技能: - 咬:bite - 抽象出类: - 人类: - 相同特征 - 生命 - 相同技能 - 咬 狗对象1: - 特征: - 生命: 250 - 名字: name = 'HCY' - 品种: dog_type = '哈士奇' - 攻击力: arg - 技能: - 咬:bite 狗对象2: - 特征: - 生命: 400 - 名字: name = 'jason' - 品种: dog_type = '哈巴犬' - 攻击力: arg - 技能: - 咬:bite 狗对象3: - 特征: - 生命: 200 - 名字: name = 'sean' - 品种: dog_type = '沙皮' - 攻击力: arg - 技能: - 咬:bite 狗类: - 相同特征 - 相同技能 - 咬 ''' #人类 class People: def __init__(self, name, life, arg): self.name = name self.life = life self.arg = arg #人调用bite时,传入狗对象 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.dog_type = dog_type self.life = life self.arg = arg #狗对象调用bite时,传入人对象 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('高地',2000, 500) d1 = Dog('HCY', 250, '哈士奇',2500) p2 = People('高地2', 5000, 50) import time while True: #开始人狗互咬 # if p1.life or d1.life: res1 = d1.bite(p2) if res1: break time.sleep(1) res2 = p1.bite(d1) if res2: break time.sleep(1)