在搞清了各类数据类型、赋值判断、循环之后若是是从C++、Java语言入手的,就会有一个深坑要过:OOP(object oriented programming):公私有保护、多重继承、多态派生、纯函数、抽象类、友元函数等等等等一堆专有名词等着你呢!还好还好!Python是一门相对友好一点的语言,他在创立之初就鼓励命令交互式的轻量级编程。理论上,Python的命令式语言是图灵完备的,也就是说命令式语言,理论上能够左到任何其余任何语言能作到的全部事情,甚至进一步,仅仅以靠汇编语言的MOV指令,就能实现图灵完备编程。html
那为何咱们不这么作呢?事实上“上古时代”的程序员就是这么作的,可随着程序功能性复杂的逐步提高,需求的不断迭代,不少老旧的代码修改起来就无比麻烦,根本没法迭代和维护,甚至只能重构。这也就是为何古老的代码称为“屎山”的缘由。程序员
传统的命令式语言有无数重复性的代码,虽然函数的诞生减小了不少重复的代码。但随着计算机的发展,只有函数是不够的,要把更加抽象的概念引入计算机才能缓解(注意是缓解而不是解决),这样OOP就应运而生。编程
一.基础概念ide
面向对象的基础概念在Python篇面向对象编程和Python面向对象进阶使用总结过,这里就再也不多说了,总之就是这四个点,虽然总结的互式很严谨,但也能够直观的了解一下:函数
1.类:一群有着类似性的事物的集合,在Python里对应的是class;单元测试
2.对象:集合中的一个失误,Python里对应由class生成的某一个object;测试
3.属性:对象的某个静态特征;idea
4.函数:对象的某个动态能力。spa
二.几种很是规:类函数、静态函数等设计
有几种函数咱们再巩固一下:
class Peaple(): NATIONALITY = 'China' #常量/类变量 def __init__(self,name,sex,age,salary=1000): #构造函数 self.name = name self.sex = sex self.age = age self.__salary = salary #私有属性 @classmethod #类方法,不能调用实例属性,只能调用类变量 def fun(self): print(self.NATIONALITY) @staticmethod #静态方法,声明时不会把self传递给函数 def fun2(test): print(test) p1 = Peaple('Jack','male',22) p1.fun()
这个例子里,就列举了经常使用的几个方法和属性(习惯问题,有些时候叫方法,也有时候叫函数):
1.类变量/常量:好比这个类里的对象都具备的属性,咱们在抽象类的时候就能够把他拿出来,在实例化的时候就不用再专门赋值了。通常类变量都是用大写字母来命名。
2.类方法:用装饰器将方法声明为类方法,在函数内没法调用在构造函数中定义的属性,只能调用上一条中的类属性。类属性还有另一种用法,返回一个类:
@classmethod def new_person(cls,name,sex,age): return cls(name=name,sex=sex,age=age) p1 = Peaple('Jack','male',22) p2 = p1.new_person('Mary','female',25)
咱们定义个类方法,而后能够经过实例调用这个类方法建立一个新的实例(还没想到有什么实际做用)
3.静态方法:静态方法已经和类没什么关联了,只是在调用的时候要加上类。最直观的例子就是相似于os的模块,导入后os里的各个方法其实和os这个类是没什么关系的,可是在调用的时候仍是要加上os
import os os.open() os.close()
4.私有属性是只有在类里的方法能够调用的,而在实例中没法调用。(一样,在定义方法的时候加上"__"注意是两道下划线就构成了私有方法,也是只能在构造类里使用,在实例中没法使用)。
三.继承
继承是面向对象里很重要的一点,说白了就是子类具备费雷的属性和函数。在下面一章结合实例应用里面咱们会着重提一下,在这里就说几点:
1.子类在实例化的时候是不会调用父类的构造函数的,必须显性的调用父类的构造函数,(super().__init__())。
2.其次,在某些定义的类的方法时候
class A(): def __init__(self): pass def fun(self): raise Exception('fun is not defined')
在父类定义fun的时候,这种方式定义出来的函数,在子类里必须重构一下,不然会raise error中断程序的执行,这种写法叫函数重写,可使子类必须从新写一遍函数来盖掉原来的函数。
3.还有一种类是抽象类,它的存在就是做为父类存在的,一旦对象化就会报错(就像PyQt5里的各类基类),
from abc import ABCMeta,abstractclassmethod class A(metaclass=ABCMeta): def __init__(self): pass @abstractclassmethod def fun(self): raise Exception('fun is not defined')
在这里A就是一个抽象类。抽象类里能够把全部子类的共同的方法都放进去,可是A类是不能直接实例化的。
这是软件功能中一个很重要的概念:定义接口。大型工程每每须要不少人合做开发,在idea提出后,开发组和产品组首先召开产品设计会,PM写出产品需求文档,而后迭代;TL(项目经理)编写开发文档,开发文档中会定义不一样模块的大体功能和接口、每一个模块之间如何写做】单元测试和继承测试、线上灰度测试、监测和日志等等一些列开发流程。抽象类就是这么一种存在,他是一种自上而下的设计风范,只须要少许的代码描述清除要作的事情,定义好接口,而后就能够交给不一样的开发人员去开发和对接。
4.注意继承的顺序:在之前那个帖子里演示过了,总结了就是一句:在Python2中经典类是按照深度优先来继承,新式类是广度优先的继承策略;而在Python3中经典类和新式类都是按照广度优先的继承策略。