Python基础-面向对象(Object Oriented
刚开始学python的时候总看见这样一句话“Python是一种纯面向对象语言,在python里面一切皆是对象”,当时并不理解这句话,在自己第一次做实际业务时,写出来的python代码总觉得很乱,自己都看不懂,后来自己学习了面向对象,对那句话有了一些理解,下面分享一下面向对象学习中的笔记和一些自己的理解。
面向对象与面向过程的区别
程序语言可以分为面向对象和面向过程两种,比如C语言是一种典型的面向过程的程序设计语言,面向对象的程序设计语言有我们熟知的Java、c++、Python等等。下面是自己在学习过程中对这两类语言的一些理解。
面向过程
- 面向过程主要是分析解决问题的步骤,然后逐步逐步的去实现,因为本人刚结婚,就以一场婚礼的筹办为例子说明:
– 发请柬(选照片、措辞、制作);
– 宴席(场地、找厨师、准备座椅、计划菜单、购买食材);
– 新房布置(装饰品购置,找同学帮忙布置);
–婚礼仪式(婚礼礼仪流程、请主持人、制作婚礼ppt)。 - 总结成一个公式:程序 = 算法 + 数据结构,其中算法就是婚礼筹办的整个步骤,括号里面代表数据结构。
- 优点:所有环节、细节都是自己在掌控
- 缺点:需要考虑所有细节,工作量大。
面向对象
- 面向对象则是只需找出解决问题的人,然后分配职责。同样以婚礼筹办为例子:
–发请柬:找婚纱摄影公司(拍照片、制作请柬);
–宴席:找酒店(告诉对方标准、数量、挑选菜品菜单);
–婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)。- 公式:程序 = 对象 + 交互,其中对象是指婚纱摄影公司、酒店、婚庆公司等等,二括号内容代表对象交互的方法。
- 优点:
思想层面:
(1)可以模拟现实场景,更接近与人类思维。
(2)有利于梳理归纳、分析解决问题。
技术层面:
(1)高复用:对重复代码进行封装,可以提高开发效率;
(2)增加新的功能时候,可以不用修改以前的代码;
(3)代码可读性强,逻辑清晰,结构比较规整。
下面对面向对象做一些简单的介绍
类和对象
要理解面向对象首先要知道什么是类,什么是对象。类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型,这句话是转至百度百科。
- 类可以理解为生活中的“类别”,比如酒店类。婚纱摄影类等等;
- 对象可以理解为归属某个类别的"个体",比如某某酒店,某某婚纱摄影基地等等;
- 类创建的对象的“模板”。
- 类与类行为不同(比如酒店与婚纱摄影公司的作用不同),对象与对象数据不同(每个具体的酒店做的菜不一样,各个婚纱摄影公司之间的具体摄影师风格不一样)。
- 类中可以定义很多方法,一个方法做一件事。比如酒店类中可以有服务员、厨师等方法,厨师只负责做菜,服务员只负责上菜。
- 而对象,在实际应用中可以实例化具体对象,比如我找某某就对负责宴席,然后该酒店这个实例对象可以调用他们的厨师做菜等等。
在这里我插入一段Python代码具体说明:
#此代码是定义一个连接Oracle数据库的类,并且定义了操作数据库的方法,因为一些业务相近,在定义类时我直接实例化了。
class ConnDatabase():
#定义一个连接数据库的类
def __init__(self):
#这个方法是一个类的初始化函数或者说方法,在这里我直接实例化连接Oracle数据库
self.dns_tns=cx_Oracle.makedsn('host','post',sid='databasename')
self.conn = cx_Oracle.connect('username','password',self.dns_tns)
self.cursor = self.conn.cursor()
def execute_db(self, sql):
#在类中定义执行sql语句的方法
self.cursor.execute(sql)
data = self.cursor.fetchone()
return data
def close_db(self):
#定义一个断开数据库连接的方法
self.cursor.close()
self.conn.close()
封装、继承、多态
说到面向对象离不开封装、继承、多态这三个特征。
封装
定义
- 数据角度:将一些基本数据类型符合成一个自定义类型,比如上面代码的def init()方法
- 行为角度:向类外面提供必要的功能,隐藏实现的细节。比如上述代码中操作数据库和断开数据库的方法,使用时直接调用该方法即可。
- 设计角度:(这个是摘抄知乎中的一些内容,我觉得总结的非常好,只是忘记作者id了。)
(1).分而治之:将一个大的需求分解为许多类,每个类处理一个独立的功能;拆分的好处是便于分工,便于服用,可扩展性强。比如上面所说的酒店的例子,某某酒店可以服务与我,也可以服务与别人,同时可以招聘新的厨师扩充其新的菜系并不影响酒店的运营。
(2).变而疏之:变化的地方独立封装,避免影响其他类。
(3).高内聚:类中每一个方法只完成一项任务,比如厨师只负责做菜,摄影师只负责拍照片,化妆师只负责化妆等等。
(4).低耦合:类与类之间的关联性与依赖性要非常低,改变一个类时,尽量较少的影响其他类。
作用
- 简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的方法与功能。
- 松散耦合,降低程序各个部分之间的依赖性。是自己的代码扩展性强。
- 数据和操作相关联,每个方法操作的是自己的数据。
继承
定义
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使得子类具有父类相同的行为。比如我们可以定义狗这个大类,这个类中有“听”,“吠”,“摇尾巴”等三个方法,那么我么可以定义一个“黄狗”类,使他继承“狗”这个大类,使得“黄狗”同样有“听”、“狗吠”、“摇尾巴”等方法功能,但是“黄狗”类有着毛色为“黄色”的自己的属性,其中“狗”类称之为“父类”,“黄狗”类是父类的“子类”。
语法
1. 代码
class 子类(父类):
def __init__(self,参数列表):
super().__init__(参数列表)
self.自身实例变量 = 参数
2. 说明
-- 子类拥有父类的所有成员。
-- 子类如果没有构造函数,将自动执行父类的,但如果有构造函数将覆盖父类的。此时必须通过super()函数调用父类的构造函数,以确保父类属性被正常创建。
优点
- 使得代码可以复用,也是一种代码的复用方式。
- 可以以层次化的方式管理类。
缺点
耦合度较高,当调用之后,需要修改某一部分代码时,可能其他代码也需要修改。
适用性
多个类在概念上一致时,可以用继承的方法进行代码的统一的处理。
多态
定义
上述继承中,父类的同一动作或者行为,在不同的子类上有不同的实现。比如在“狗”类中,不同种类的叫声不一样,当腰调用某种狗类时,可以对“吠”这个方法进行重构,这就是多态的概念。
作用
- 继承相关概念的共性进行抽象,多态在共性基础上,体现类型的个性化,即一个行为有不同的实现方式。
- 增强代码的扩展性。
面向对象的设计原则
开闭原则
对扩展开放,对修改关闭。即对于调用者可以对其扩展,但是不能对封装的实现细节进行修改。(重构是属于扩展)
增加新功能,不改变原有代码。
类的单一原则
一个类有且只有一个改变它的原因。即一个类只有
依赖倒置
客户端代码调用的类尽量依赖或使用抽象的组件;
抽象是稳定的,实现是多变的。
组合复用原则
如果仅仅为了代码复用优先选择组合关系,而非继承关系。
组合的耦合度低于继承,灵活度高于继承。
(这部分笔者暂时也还没有理解)
里氏替换
父类出现的地方可以被子类替换,再替换后依然保持原有功能。
子类要拥有父类的所有功能。
子类在重构父类方法时,尽量选择扩展重写,防止改变了功能。
迪米特法则
类与类交互时,在满足功能要求的基础上,传递的数据越少越好。因为这样可能降低耦合度,代码后期容易维护。