初识面向对象
本节主要内容:
1. ⾯向对象和⾯向过程
2. ⾯向对象如何编写
3. ⾯向对象三⼤特征
⼀. ⾯向对象和⾯向过程(重点理解)
1. ⾯向过程: ⼀切以事物的流程为核⼼. 核⼼是"过程"⼆字, 过程是指解决问题的步骤,
即, 先⼲什么, 后⼲什么. 基于该思想编写程序就好比在编写⼀套流⽔线. 是⼀种机械
式的编程思维
优点: 负责的问题流程化, 编写相对简单
缺点: 可扩展性差
2. ⾯向对象: ⼀切以对象为中⼼.
什么是对象? 不好解释. 先解释解释什么是⻋? 有轱辘, 有⽅向盘, 有发动机, 会跑的
是⻋. 好. 在解释⼀个. 什么是⼈. 有名字, 年龄, 爱好, 会唱歌跳舞思考的是⼈. 我们给这两个
东⻄下了⼀个简单的定义. 总结: 具有相同属性和动作的结合体叫对象. ⾯向对象思维, 要⾃
⼰建立对象. ⾃⼰建立场景. 你是就是⾯向对象世界中的上帝. 你想让⻋⼲嘛就⼲嘛. 你想让
⼈⼲嘛⼈就能⼲嘛
优点: 可扩展性强
缺点: 编程的复杂度⾼于⾯向过程
对比:
说. 要把⼤象装冰箱, 总共分⼏步? 三步. 第⼀步. 打开冰箱⻔, 第⼆部. 装⼤象, 第三
部. 关冰箱⻔. 这是⼀个典型的⾯向过程的思维⽅式. 来我们如果换成⾯向对象呢? 很简单. 想
办法造⼀个会钻冰箱的⼤象就可以了. 然后命令⼤象. 进冰箱. ⼤象就乖乖的进冰箱了. 这就
是⾯向对象思维. 我们⾯向的不再是事物发展的流程, ⽽是操纵某⼀个事物的个体. 具体的某
⼀个事物.
⼆. ⾯向对象如何编写
说了这么多. ⾯向对象的程序如何编写呢? 想想在我们的世界中. 我们如何造⼀辆⻋?
先由设计师来设计图纸. 设计师在图纸上勾勒出⻋应该是xx样的. 应该有什么. 以及这台⻋的
功能等等. 然后交给⼯⼚进⾏代⼯. 根据设计师设计的图纸去创造⻋. 程序也⼀样. 我们需要
先设计⼀个图纸. 在图纸上把我要创建的对象进⾏描述. 然后交给⼯⼈去创建对象.
在这⾥, 我们画图纸的过程需要我们写类, 我们⽤类来描述⼀个对象. 类的语法很简单.
class 类名: pass
哦了, 这就创建出类了. 假设. 我们创建⼀个⻋类.
class Car: pass
这就创建了⼀个类. 图纸有了. 怎么创建⼀辆⻋呢? 也很简单. 我们把图纸交给⼯⼈帮我
们创建⼀个⻋的实例. 这个过程被称为实例化. 实例化只需要: "类名()"就可以了
c = Car() # 创建⼀辆⻋
⻋有了. 我们的⻋⾄少得有个颜⾊, ⻋牌, 排量等等信息啊. 不同的⻋, 有不同的颜⾊, ⻋
牌, 排量等.
c.color = "red" c.pai = "京A66666" c.pailiang = "1.6T" print(c.color) print(c.pai) print(c.pailiang)
我们使⽤"对象.特征"可以给对象设置属性信息,
接下来, 再造⼀辆⻋, 并给⻋设置相关的属性信息
c2 = Car() c2.color = "white" c2.pai = "京B22222" c2.pailiang = "2.0T" print(c1) print(c2)
我们发现, 这两量⻋是完全不同的两量⻋. 但是. 拥有相同的属性和信息. 是不是有点⼉
冗余了? 怎么办呢? 想想. 我们把⻋的信息如果写在类⾥是不是会更好呢? ⽽且. 我的⻋在创
建的时候这些信息应该已经是设计好了的. 不应该是后天设计的. 好了, 我们知道需求了, 在
创建对象的时候能给对象设置⼀些初始化的属性信息. 在python中我们可以是⽤__init__(self)
函数给对象进⾏初始化操作. 这个函数(⽅法)被称为构造函数(⽅法).
class Car: def __init__(self, color, pai, pailiang): # self表示当前类的对象. 当前你创建 的是谁, 谁来访问的这个⽅法.那这个self就是谁. self.color = color self.pai = pai self.pailiang = pailiang c1 = Car("red", "京A66666", "1.6T") c2 = Car("white", "京B22222", "2,0T") print(c1.color) print(c2.color)
通过打印, 我们发现. 这两个对象依然像原来那样可以完成属性的设置.
属性设置完了. 接下来. ⻋不光有这些信息啊. ⻋还会跑呢. 跑是⼀个动作. 所以我们要
把跑写成⼀个函数. 但是在⾯向对象编程中. 我们不应该叫函数了, 改成叫⽅法. 只不过这个
⽅法写起来比正常的⽅法多⼀个参数self. 仅此⽽已.
class Car: def __init__(self, color, pai, pailiang): # self表示当前类的对象. 当前你创建 的是谁, 谁来访问的这个⽅法.那这个self就是谁. self.color = color self.pai = pai self.pailiang = pailiang def run(self, speed): print("⻋可以跑%speed) c = Car("red", "京A66666", "2.0T") c.run(100) # 这时. python会⾃动把对象c传递给run⽅法的第⼀个参数位置.
总结: 类与对象的关系: 类是对事物的总结. 抽象的概念. 类⽤来描述对象. 对象是类的实例
化的结果. 对象能执⾏哪些⽅法. 都由类来决定. 类中定义了什么. 对象就拥有什么
三. ⾯向对象的三⼤特征
⾯向对象三⼤特征: 封装, 继承, 多态. 只要是⾯向对象编程语⾔. 都有这三个特征.
1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对
象, 打包成模块. 这都属于封装的思想. 具体的情况具体分析. 比如. 你写了⼀个很⽜B
的函数. 那这个也可以被称为封装. 在⾯向对象思想中. 是把⼀些看似⽆关紧要的内容
组合到⼀起统⼀进⾏存储和使⽤. 这就是封装.
2.继承: ⼦类可以⾃动拥有⽗类中除了私有属性外的其他所有内容. 说⽩了, ⼉⼦可以
随便⽤爹的东⻄. 但是朋友们, ⼀定要认清楚⼀个事情. 必须先有爹, 后有⼉⼦. 顺序不
能乱, 在python中实现继承非常简单. 在声明类的时候, 在类名后⾯添加⼀个⼩括号,
就可以完成继承关系. 那么什么情况可以使⽤继承呢? 单纯的从代码层⾯上来看. 两
个类具有相同的功能或者特征的时候. 可以采⽤继承的形式. 提取⼀个⽗类, 这个⽗类
中编写着两个类相同的部分. 然后两个类分别取继承这个类就可以了. 这样写的好处
是我们可以避免写很多重复的功能和代码. 如果从语义中去分析的话. 会简单很多. 如
果语境中出现了x是⼀种y. 这时, y是⼀种泛化的概念. x比y更加具体. 那这时x就是y的
⼦类. 比如. 猫是⼀种动物. 猫继承动物. 动物能动. 猫也能动. 这时猫在创建的时候就
有了动物的"动"这个属性. 再比如, ⽩骨精是⼀个妖怪. 妖怪天⽣就有⼀个比较不好
的功能叫"吃⼈", ⽩骨精⼀出⽣就知道如何"吃⼈". 此时 ⽩骨精继承妖精. 话不多说.
上代码。
class Yao: def chi(self): print("我是妖怪, 我天⽣就会吃⼈") class BaiGuJing(Yao): # ⽩⻣精继承妖怪 pass bgj = BaiGuJing() bgj.chi() # 我是妖怪, 我天⽣就会吃⼈ # 虽然⽩⻣精类中没有编写chi. 但是他爹有啊. 直 接拿来⽤
在python中, ⼀个类可以同时继承多个⽗类. 说⽩了, 现在⼀个⼉⼦可能会有多个爹了.
既然是有这么多个爹, 总得有远有近. 比如. 有⼀个这样的⽜B的⼈物, 叫锅不美. 就有很多个
爹嘛.
class QinDie: def chi(self): print("亲爹给你好吃的") def play(self): print("亲爹会陪你玩") class GanDie: def qian(self): print("⼲爹给钱啊") def play(self): print("⼲爹会陪你玩") class GuNiang(QinDie, GanDie): pass bumei = GuNiang() bumei.chi() # 亲爹 bumei.qian() # 亲爹没有, 找⼲爹 bumei.play() # 亲爹有了, 就不找⼲爹了
具体的MRO(method resolution order)算法. 我们到后⾯会具体进⾏分析和讲解.
3.多态: 同⼀个对象, 多种形态. 这个在python中其实是很不容易说明⽩的. 因为我们⼀
直在⽤. 只是没有具体的说. 比如. 我们创建⼀个变量a = 10 , 我们知道此时a是整数
类型. 但是我们可以通过程序让a = "alex", 这时, a⼜变成了字符串类型这是我们都
知道的. 但是, 我要告诉你的是. 这个就是多态性. 同⼀个变量a可以是多种形态. 可能
这样的程序和说法你还get不到具体什么是多态. 接下来. 我们来看⼀个程序. 北京动
物园饲养员alex⼀天的⼯作. 从早上开始喂养猪, 中午喂哈⼠奇, 晚上还得喂阿拉斯加.
来我们⽤代码实现这样的代码:
class Animal: def chi(self): print("动物就知道吃") class Pig(Animal): def chi(self): print("猪在吃") class Haski(Animal): def chi(self): print("哈⼠奇在吃") class Alasika(Animal): def chi(self): print("阿拉斯加在吃") class SiYangYuan: def yanng_animal(self, ani): ani.chi() zhu = Pig() erha = Haski() ala = Alasika() alex = SiYangYuan() alex.yanng_animal(zhu) alex.yanng_animal(erha) alex.yanng_animal(ala)
多态的好处: 程序具有超⾼的可扩展性. ⾯向对象思想的核⼼与灵魂. python⾃带多态.