一、编程范式
程序员通过特定的语法+数据结构+算法告诉计算机如果执行任务,实现这个过程有不同的编程方式,对这些不同的编程方式进行归纳总结得出来的编程方式类别,即为编程范式
编程范式:面向过程编程、面向对象编程、函数式编程
二、面向对象编程 OOP编程
面向对象编程的使用场合:
1、需要设定一个模板
2、几个对象拥有相同的参数
3、连接数据库、备份数据库,测试备份文件可用性
面向对象编程的核心特性:
1、类 class
类及时就有相同属性对象的原型/模板,类中封装了对象的共同属性和方法
1 class English(object): 2 def __init__(self,name,age): #构造函数 构造方法=初始化方法 3 self.name=name #成员属性 4 self.age=age 5 def approch(self): 6 print('%s %age are learning English '%(self.name,self.age)) 7 person1=English('小楠','23') #进行实例化, 实例化后产生的对象就是实例,通过__init__()接受参数 8 person1.approch()
①每个def 函数中都至少一个self参数
②第一个函数__init__(self)为构造函数(方法),或者叫初始化函数,类被实例化的时候会自动调用这个方法
③函数approach(self) 叫做类的方法,动态方法
注意类除了有动态方法,还有一个静态方法,动态属性中参数必须有self,如果需求中有的函数不需要传入这个参数,可以用静态属性来设定一个函数@staticmethod
1 class one(object): 2 @staticmethod 3 def n1(): #不需要必须填写self,可以传入其他参数 4 print('我是一个静态方法') 5 one.n1() #不需要实例化,直接通过类来调用
有上密码呢代码可以看出,静态方法的特性:
① 静态方法也存在于类中,但是不需要self参数,可以是任意个
② 静态方法的调用可以直接调用,不需要实例化,通过类调用即可
④析构方法:
#析构函数:__del__ class one(object): def __init__(self,name): self.name=name def fun(self): print('%s is classy'%self.name) def __del__(self): print('del.................') per1=one('songxiaonan') per1.fun() '''__init__:构造函数 __del__:删除已经构造的函数'''
2、对象
类需要实例化之后才可以被调用, 类实例化之后就是一个实例,即对象。 一个类可以被多次实例化,每个实例(对象)也可以用不同的属性和方法
比如:有一个one1类, 实例化两次
1 person1=English('小楠','23') #进行实例化, 实例化后产生的对象就是实例,通过__init__()接受参数 2 person1.approch()
实例化后既可以通过实例来调动类中的方法
3、封装
类封装了:属性和方法
对象封装了:成员属性
类中的属性:成员属性,共有属性,私有属性
1 class one(object): 2 country='China' # 公有属性 3 def __init__(self,name,age): 4 self.name=name # 成员属性 5 self.age=age 6 self.__weight=30# 私有属性 7 def shot(self): 8 print('message:%s %s' %(self.name,self.age) )
私有属性:外部不可以访问,只能在类内部访问的属性。以__开头:self.__name
①如何在外部可以访问私有属性呢?
在类的内部定义一个方法,返回私有属性值,然后在外部调用这个方法
class one(object): country='China' def __init__(self,name): self.name=name self.__weight=30# 私有属性 def weight(self): #返回私有属性值,外部就可以访问私有属性了 return self.__weight d1=one('song',22) print(d1.weight()) # 30
②如果想通过重新定义一个函数访问,也可以强制访问
1 print(d1._one__weight) # 30
公有属性:在类中直接定义,而不是再构造方法中
共有属性和构造方法、类的其他方法是平级的,类中的所有方法可以共享该属性
class one(object): country='China' #共有属性 def __init__(self,name,age): self.name=name self.age=age d1=one('song',22) print(d1.country) # 输出 China print(one.country) # 输出 China
共有属性可以通过实例调用,也可以直接通过类来调用
修改共有属性: 是通过类调用该属性进行修改,而不是实例调用该属性进行修改
one.country='US' print(d1.country) # 输出 US print(one.country) # 输出 US d1.country='Japan' #注意:这里并不是在修改类的共有属性,而是又重新定义了一个成员属性,和原有的共有属性没有关系 print(d1.country) # 输出 Japan print(one.country) # 输出 China
4、继承
继承是面向对象的一个重要特性,继承可以保留原来的功能,又可以在不需要重新编写前类的情况下,对这些功能进行扩展
基类:one1
1 class one1(object): 2 country='China' 3 def __init__(self,name,age): 4 self.name=name 5 self.age=age 6 self.__weight=30 7 def shot(self): 8 print('message:%s %s' %(self.name,self.age) ) 9 def weight(self): 10 return self.__weight
子类:n1
class n1(one1): def n1_func(self): print('%s 的兴趣是:%s'%(self.name,self.hobby)) p1=n1('宋晓楠','22') p1.shot() # 直接可调用父类的shot方法 message:宋晓楠 22 p1.n1_func() # 子类自己的方法 宋晓楠 的兴趣是:学习
如果子类需要有新的参数出入,那么就需要对类的构造方法进行重构,但是子类重构父类的方法后,就会覆盖父类的构造方法,那么如何不覆盖父类的初始化函数同时又重构自己的初始化函数呢? ——先继承,再重构
class n1(one1): def __init__(self,name,age,hobby): #如果子类 没有传入新参数的需求,就不需要重构__init__() one1.__init__(self,name,age) #先继承,再重构 经典类写法 #上句代码 等同于=super(n1,self)__init__(self,name,age) 新式类写法 self.hobby=hobby def n1_func(self): print('%s 的兴趣是:%s'%(self.name,self.hobby)) p1=n1('宋晓楠','22','学习') p1.shot() # 直接可调用父类的shot方法 message:宋晓楠 22 p1.n1_func() # 子类自己的方法 宋晓楠 的兴趣是:学习
4.1 多继承:多个父类继承、多级继承
1、继承多个父类
1 class School(object): 2 def info(self): 3 print('我是另外一个父类') 4 class Teacher(SchoolMessage,School): # 继承多个类 5 def __init__(self,name,age,sex,sala,course): 6 SchoolMessage.__init__(self,name,age,sex) 7 self.sala=sala 8 self.course=course 9 def teaching(self): 10 print('我是 %s 老师,所授课程是:%s'%(self.name,self.course)) 11 t1=Teacher('小花',30,'女','10000','数学') 12 t1.info() # 输出:我是另外一个父类
2、多级继承
py3中无论是经典类和新式类,继承调用的时候,都是广度查找:先查找上一级中,上一级没有再去查找上上级'''
class F1(object): def __int__(self): print('F1') def a1(self): print('F1a1') def a2(self): print('F1a2') class F2(F1): def __int__(self): print('F2') def a1(self): self.a2() print('F2a1') def a2(self): print('F2a2') class F3(F2): def __int__(self): print('F3') def a2(self): print('F2a3') obj=F3() obj.a1() #多级继承 进行广度查找
'''输出: F2a3 F2a1'''
5、多态
作用:接口的重用
1 class Animal(object): 2 def talk(self): 3 raise NotImplementedError('必须被子类调用才可以。。') 4 # a=Animal() 5 # a.talk() # NotImplementedError: 必须被子类调用才可以。。 6 7 class cat(Animal): 8 def talk(self): 9 print('cat') 10 class dog(Animal): 11 def talk(self): 12 print('dog') 13 14 b=cat() 15 b.talk() 16 c=dog() 17 c.talk()
现在只能通过两个实例 b和c分别来调取talk才可以实现talk方法
多态的意义在于,值通过一个接口就可以实现cat和dog的talk,
比如: 只通过Animal(obj) 这个接口 将b和c分别传入 就可以实现不同实例的talk
目前 这个需求多态的实现方法:
def Animal(obj): #在类外面定义一个函数,将实例单过参数传进去 obj.talk() Animal(b) Animal(c)