本节重点
了解面向对象、面向过程的区别
掌握什么是类,什么是对象
掌握如何定义及使用类和对象
了解类与对象间的关系
掌握类属性和实例属性
掌握绑定方法
一.编程范式
编程即写程序or写代码,具体是指程序员用特定的方法+数据结构+算法编写代码,目的是用来告诉计算机如何执行任务。
如果把编程的过程比喻为练习武功,那么编程范式值的就是武林中的各种流派,而在编程的世界里最常见的两大流派就是:面向过程和面向对象。
“功夫”的流派没有高低之分,只有习武的人才有高低之分,在编程世界里更是这样,面向过程与面向对象在不同的场景下都各有优劣,谁好谁坏不能一概而论,下面就让我们来详细了解它们。
二.面向过程设计
面向过程:核心是“过程”二字,“过程”指的是解决问题的步骤,即先干什么...再干什么......,基于面向过程设计程序就好比在设计一条流水线,是一种机械式的思维方式。若程序一开始是要着手解决一个大的问题,面向过程的基本设计思路就是把这个大的问题分解成很多歌小问题或子过程,这些子过程在执行的过程中继续分解,直到小问题足够见到到可以在一个小步骤范围内解决。
优点是:复杂的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
缺点是:一套流水线或者流程就是用来解决一个问题,比如生产契税的流水线无法生产汽车,即便是能,也得大改,改一个组件,与其相关的组件都要修改,牵一发而动全身,扩展性极差。
应用场景:面向过程的程序设计思想一般用于那些功能一旦实现之后就很少需要改变的场景,如果你知识写一些简单的脚本,去做一些一次性任务,用面向过程的方式是极好的,著名的例子有Linux内核,git,以及Apache Http Server等。但如果你要处理的任务是复杂的,且需要不断迭代和维护的,那还是用面向对象更方便了。
三.面向对象设计
面向对象:核心是“对象”二字,要理解对象为何物,必须把自己当成上帝,在上帝眼里,世间存在的万物皆为对象,不存在的也可以创造出来。基于面向对象设计程序就好比在创造一个世界,世界是由一个个对象组成,而你就是创造对象的上帝。
与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的而非流程的模拟,是一种“上帝式”的思维方式。
优点是:解决了面型过程可扩展性低的问题。需要强调的是,对于一个软件质量来说,面向对象的程序设计并不代表全部,面向对象的程序设计只是用来解决扩展性问题。
缺点是:编程的复杂度远高于面向过程,不了解面向对象而立即上手并基于它涉及程序,极容易出现过度设计的问题,而且在一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本程序就不适合面向对象去设计,面向过程反而更加适合。
应用场景:当然是应用于需求经常变化的软件中,一般需求的变化都几种在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。
四.类与对象
1.类与对象概念
类即类别、种类,是面向对象设计最重要的概念。对象是特征和技能的结合体,而类则使一系列对象相似的特征和技能的结合体。
在现实生活中:先有对象,再有类
再程序总:先定义类,后产生对象
2.定义类
class School:
name = 'qinghua'
def learn(self):
print('is learning')
def eat(self):
print('is eating')
def sleep(self):
print('is sleeping')
注意
类中可以有任意python代码,这些代码在勒定义阶段便会执行,因而会产生新的名称空间,用来存放类的变量名和函数名,可以通过School.__dict__ 查看
类中定义的名字,都是类的属性,点事访问属性的语法
对于经典类来说我们可以通过该字典操作类名称空间的名字,但新式类有限制(新式类与经典类的区别我们将在后续章节介绍)
五.类属性和实例属性
类属性:School.name
实例属性:s = School()
s.addr = '北京'
六.属性查找与绑定方法
1.属性查找
类的数据属性是所有对象共享的
类的函数数据是绑定给对象使用的,称为绑定到对象的方法
2.绑定方法
类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但是必须遵循函数的使用规则,有几个参数就传几个参数。
class School:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex =sex def learn(self):
print('%s is learning') s1 = School('清华',18,'男')
School.learn(s1)
s1.learn()
类中定义的函数(没有别任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象时其实是不同的方法。
强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)
s1.learn() # 等同于School.learn(s1)