一、什么是面向对象编程
核心是“对象”二字,对象指的是“特征与技能”的结合体。
基于该编程思想编写程序,就好比在创造世界,一种 “上帝式” 的思维方式。
优点:可扩展性强
缺点:编程的复杂度远高于面向过程
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
二、类与对象
类即类别、种类,是面向对象设计最重要的概念。对象是特征与技能的结合体,而类则是一系列对象相同的特征与技能的结合体
那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看
从两种角度:
-现实世界中:
先有对象,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念。对象是具体存在的,而类只是一种抽象概念。
-在程序中:
务必保证先定义类,再通过“调用类,产生对象”。
在程序中,务必保证:先定义(类),后使用(产生对象) PS: 1. 在程序中特征用变量标识,技能用函数标识 2. 因而类中最常见的无非是:变量和函数的定义 #程序中的类 定义类的命名规范:驼峰体 class BjdxStudent: #类名指向的是类的内存地址 #用变量表示特征,在类中的特征 也称之为 “属性” attribute school = 'Bjdx' #用函数表示技能 #注意: 在类内部定义函数,会默认有一个参数self def learn(self): #self此时当做一个形参 print('is learning...') print(BjdxStudent) # <class '__main__.BjdxStudent'> ''' 注意:在定义类的阶段会立刻执行类体内的代码,然后将产生的名字存放于类的名称空间中 ''' #查看类的名称空间 print(BjdxStudent.__dict__) print(BjdxStudent.__dict__['school']) print(BjdxStudent.__dict__['learn']) BjdxStudent.__dict__['learn'](123) 类提供一种特殊获取名字的方式 “类名.名字” 的方式 # 查 print(BjdxStudent.school) #Bjdx print(BjdxStudent.learn) #函数的内存地址 调用类里面的函数的时候必须要传参,如下: BjdxStudent.learn('tank') #此时learn里面必须要加参数。 #is learning... # 改 BjdxStudent.school = 'beijing' print(BjdxStudent.school) #beijing # 删 del BjdxStudent.school # 增 BjdxStudent.school = 'Bjdx' print(BjdxStudent.school) #bjdx BjdxStudent.bjdx_student = 'BH' #重点 print(BjdxStudent.bjdx_student) #BH print(BjdxStudent.__dict__) #类的名称空间里里面多了 'bjdx_student': 'BH' ''' 注意区别: - 函数的名称空间: 在调用函数时产生,函数调用结束后销毁。 - 类的名称空间: 在定义阶段时产生,会将类中所有的名字,扔进类的名称空间中。 '''
三、对象的产生
在程序中:必须调用类产生对象
类名+() 即调用类,产生对象
类的实例化: 调用类的过程称之为类的实例化,产生的对象也可以称之为类的一个实例。
class Student: school = 'bjdx' def learn(self): print(self) print('learning...') stu1 = Student() stu2 = Student() stu3 = Student() print(stu1) #<__main__.Student object at 0x0000025C4BC52548> print(stu2) #<__main__.Student object at 0x0000025C4BC537C8> print(stu3) #<__main__.Student object at 0x0000025C4BC5CE88>
四、对象绑定方法的特殊之处
class BjdxStudent: school = 'bjdx' def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def learn(self): print('%s is learning...' %self.name) stu1 = BjdxStudent('李三胖',18,'male') stu2 = BjdxStudent('王大炮',20,'male') print(BjdxStudent.learn) print(stu1.learn) print(stu2.learn) #三者的内存地址都不一样 >>> function BjdxStudent.learn at 0x0000021CB0AAC9D8> >>> <bound method BjdxStudent.learn of <__main__.BjdxStudent object at 0x0000021C999D0508>> >>> <bound method BjdxStudent.learn of <__main__.BjdxStudent object at 0x0000021C999D75C8>> 1.类内部定义的函数,类可以使用,但类来用的时候就是一个普通函数,普通函数有几个参数,就传几个参数 print(BjdxStudent.learn) BjdxStudent.learn(123) 2.类内部定义的函数,其实是给对象使用的,而且是绑定给对象用,绑定给不同的对象就是不同的绑定方法。 print(stu1.learn) #BjdxStudent.learn(stu1) print(stu2.learn) #BjdxStudent.learn(stu2) 3.绑定方法的特殊之处在于,谁来调用,就会将谁当作第一个参数自动传入 stu1.learn() #李三胖 is learning... stu2.learn() #王大炮 is learning...
总结:
1.查看类与对象的名称空间 类.dict 对象.dict
2.类中数据属性(类中的变量): 类中属性是给对象共享的,对象引用类中的属性,指向的都是类中同一个内存地址。
3.类中的方法(类中的函数): 类中的方法是给对象使用的。
由不同的对象来调用就会将方法绑定给不同的对象, 并且会将对象当做第一个参数传入。
格式
1.控制类名必须用驼峰体: 2.类体必须有文档注释 class Mymeta(type): school = 'Qinghua' def __init__(self,class_name,class_bases,class_dic): if class_name.islower(): raise TypeError('类名必须使用驼峰体') doc = class_dic.get('__doc__') if doc is None: raise TypeError('类体中必须有文档注释') #Teacher=Mymeta('Teacher',(object,),{...}) class Teacher(object,metaclass=Mymeta): #metaclas--->元类 school = 'Qinghua' def __init__(self,name,age,sex): #self--->Teacher self.name=name self.age=age self.sex=sex def score(self): print('%s is scoring' %self.name) print(Teacher.__dict__)