面向对象编程
一 面向对象编程与面向过程编程
1 面向过程编程思想
该思想核心是过程,指的是解决问题的步骤,即先干什么然后干什么,就像流水线一样,必须一步一步来,基于面向过程编程的是一种机械化的思维方式。
优点: 复杂问题流程化,简单化;
缺点:可扩展性较差。
应用场景:一旦完成几乎不会改变,像Linux内核、git以及Apache HTTP Server等
2 面向对象编程思想
随着硬件的快速发展,业务需求越来越复杂,以及编程应用领域越来越广泛,面向过程编程已经不能满足需求了,于是另一种编程思想开始兴起,就是面向对象编程。
该思想核心是对象,对象是特征与技能的结合体,基于面向对象设计程序就好比自己是造物主一样,想要创造什么就创造什么,与面向过程机式的思维方式形成鲜明对比,面向对象更加注重对现实世界的抽象化。
优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反应到整个体系中。
缺点:1. 编程的复杂度高于面向过程编程,不了解面向对象而立即上手基于对象设计程序,容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会增加编程难度。
- 无法向面向过程的程序设计流水式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等
面向对象的程序设计并不是全部。对于一个软件质量来说,,面向对象的程序设计只是用来解决扩展性。
一个好的应用软件应包括的特性:
二 类与对象
一 类的定义
类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列具有相似特征与技能的抽象概念。
在现实中是先出现对象,然后根据一系列具有相同特征的对象定义不同的类,对象是具体的存在,而类仅仅只是一个概念,并不真实存在。
在程序中是先定义类,然后根据类产生对象,这与函数的使用是类似的,先定义函数,类同理,在程序中需要先定义类,后调用类,与函数不一样的是,调用函数会执行函数体代码返回的是函数的执行结果,而调用类会产生并返回一个对象。
在程序中,务必保证,先定义类,后使用对象。
- 在程序中特征使用变量标识,技能使用函数标识。
- 因而类中最常见的是:变量和函数的定义。
# 定义一个类
class something:
school = 'hashangda'
def learn(self):
print('something is learning')
def eat(self):
print('something is eating')
def sleep(self):
print('something is sleeping')
注意:
- 类中可以为任意python代码,这些代码在类定义阶段便会执行;
- 因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过something.____dict____查看;
- 对于经典类来说可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供了专门的语法进行访问;
- 点事访问属性的语法,类中定义的名字,都是类的属性(变量和函数).
二 程序中类的用法
在程序中用.来访问类的属性,本质操作为____dict____
something.school # 等于经典类 something.__dict__['school']
something.school = 'oldboy' # 等于经典类 something.__dict__['school'] = 'oldboy'
something.name = 'musibii' # 等于经典类 something.__dict__['name'] = 'musibii'
del something.name # 等于经典类 something.__dict__.pop('name')
在程序中调用类(实例化对象),产生并返回一个对象,产生的对象会具有类里面的属性,并且可以通过句点法进行访问.
总结:
- 类本质是一个名称空间,或者说是一个用来存放变量与函数的容器;
- 类的用途之一就是当做名称空间从其内部取出名字来使用;
- 类的主要用途是调用类产生对象.
三 对象的使用
通过调用类产生的对象成为类的实例化,调用类的返回值称之为类的一个对象/实例.
some = something() # 产生一个实例对象,对象可以通过句点法访问类中的属性()
print(some.school)
# 结果 hashangda
类中定义的属性是由该类产生的所有对象共有的属性,那么每个对象自己特有的属性应该怎么定义的?
class something:
school = 'hashangda'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
类中的init方法是用来初始化一个实例对象的,并且会执行下面的代码,所以这时候要实例化对象是需要传入后面的参数.
some1 = something('musibii', 18, 'male')
some2 = something('thales', 20, 'female')
some3 = something('maffia', 22, 'male')
这样实例化出来的对象除了school属性值一样,其他都是自己独有的属性值.
调用类产生了
- 先产生一个空对象some1,然后返回;
- 触发类中函数init的执行,将对象联通调用类括号内指定的参数一同传入init.
总结:init的功能,在实例化时为对象初始化自己独有的特征(不能有返回值)
四 属性查找
属性查找和之前学的名称空间查找顺序逻辑一样,首先在对象的名称空间里面查找,没有的话去类名称空间查找,但是不会去全局名称空间查找对象的属性.
类中定义的变量是所有对象共享的,对象可以使用,类也可以使用,类一旦改变自己的属性的值,所有的对象也会随之改变.
五 绑定方法
类中定义的变量是类的数据属性,类和对象都可以使用,并且属性的值都指向一个内存地址;
类中定义的函数是类的函数属性,类和对象都可以调用,类来调用的就是一个普通的函数,但类中定义的函数都是用来给对象用的,而且是绑定给对象的.
- 类的函数:该传几个参数就传几个
- 绑定方法,指向类的函数:特殊之处是绑定给哪个对象就应该由哪个对象来调用,调用的时候就会把对象本身当做第一个参数自动传入.
六 一切皆对象
在python3中统一了类和类型的概念,就是说一个类等于一种类型,比如python中的数据类型,我们也可以定义属于自己的类
class muSibii:
pass
musibii = muSibii()
print(type(musibii))
# 结果 <class '__main__.muSibii'>