首先面向对象编程 不是在python 中有,几乎大部分的高级编程语言都是支持的。 面向对象编程 是一种编程思想,是一种写代码的一种思维, 这里 我们就以python语言为例 来介绍 什么是 面向对象编程 。
说到面向对象编程,就要提到面向过程编程 这是两种编程思想。
面向过程 一般比较好理解,比如 我要实现一个功能,函数 。我首先 就要知道 我第一步 要做什么,第二步做什么 ,第三步做什么,最后做什么。
举个例子:
比如我每天早上 去上班,我需要怎么做呢?
第一 我要早早的先起床,虽然我很懒,但是还是要起来。
第二 我要开始准备洗漱吃饭,
第三 我要去公交站台。
第四步 等车,然后上车,
第五步 等指定站台下车,步行到公司。
上面的思考问题的过程 其实 就是 面向过程一种思考模型, 按照步骤,一步 一步 最后完成 任务。
根据上面的思考,我们很容易写出来 下面的代码,清晰流畅。没有任何问题。
# -*- coding: utf-8 -*-
import time
def go_office():
"""
比如我每天早上 去上班,我需要怎么做呢?
第一 我要早早的先起床,虽然我很懒,但是还是要起来。
第二 我要开始准备洗漱吃饭,
第三 我要去公交站台。
第四步 等车,然后上车,
第五步 等指定站台下车,步行到公司。
:return:
"""
print("我要早早的先起床,虽然我很懒,但是还是要起来。")
time.sleep(1)
print("我要开始准备洗漱吃饭")
time.sleep(1)
print("我要去公交站台。")
time.sleep(1)
print("等车,然后上车,")
time.sleep(1)
print("等指定站台下车,步行到公司")
time.sleep(1)
if __name__ == '__main__':
go_office()
下面 来谈谈 面向对象 的思考方式 ,
在面向对象的编程思想的方式中 ,是这样 思考的,我要去 到公司,我要怎么做呢? 我需要有一辆车,我启动车开车到公司。 或者 是 我需要有辆 公交车,带我去公司去。 就这样, 这就是面向对象 要思考的事情。
这里 可以 把 我, 公司, 一辆车 , 公交车 这样的名词 ,在面向对象的世界里面,这些都可以称作一个叫类
的一个东西。
在python中如何定义一个类呢?
只要一个关键字 class
定义一个类
class Frank:
pass
上面的方法,定义了一个类 ,只是这个类就只有一个类名。好,现在 开始 按照面向对象的方法,来实现 去公司这个操作。
# -*- coding: utf-8 -*-
import time
class Car:
"""
出租车
"""
pass
def start(self):
time.sleep(1)
print("开车 去公司")
class Bus:
"""
公交车
"""
def start(self):
time.sleep(1)
print("做公交 去公司")
class Frank:
bus = Bus()
pass
@classmethod
def go_office(cls):
cls.bus.start()
if __name__ == '__main__':
# go_office()
Frank.go_office()
这里 我定义了一个类 Car, Bus 这些类中 有一个方法 start , 还有一个Frank 类 这个里面 有一个 Bus 类创建的一个对象bus
, 然后 在 Frank 类中 有一个 go_office 方法, 这个方法 完成了 Frank 去公司这个操作。
这个例子可能 没有那么恰当 来解释清楚 面向对象 和面向过程 这两种编程思想 的 好处,或者缺点。
我在来举个例子 我感觉相对好一些来说明这个问题。
从 面向过程
到 面向对象
的一些思考过程?
假如 现在要求一个四边形的周长,知道四个点坐标,来求 这个四边形的周长
只要把 四个点 两个点之间的距离 算出来,然后相加,就可以了, 假设有以下 4个点 ,
在 square 的list 中,好 很快 就能写好了代码。如下
square = [(1, 1), (1, 2), (2, 2), (2, 1)]
def distance(p1, p2):
return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)
def perimeter(polygon): # polygon 多边形
perimeter = 0
points = polygon + [polygon[0]]
# print(f'{points}')
for i in range(len(polygon)):
print(f"{i},{points[i]},{points[i+1]}")
perimeter += distance(points[i], points[i+1])
return perimeter
perimeter(square) # 4
我们用面向 对象思想来思考
首先思考 求周长, 首先 计算四个点之间的距离, 然后 把边长加起来就可以了。 那我们 可不可以,把点这个 东西 抽象 出来作为一个类呢?
记住面对对象 编程 首先 要思考 在完成一个任务里面 可以抽象出一个类
,然后用这个类 来完成 对数据的操作。
首先 我想把 点 这个 东西 可以抽象一个类,这个类里面有 一个坐标(x,y)
, 然后 可以通过这个类 来计算 另一个点的距离, 其实 就是 刚刚写的 求距离的函数 。
我们还要 思考 求周长 能不能 想办法 抽象一个类出来呢, 如果你想不到 也没有关系,其实可以抽象 一个 多边形的类, 然后 由这个多边形 来计算周长,这样计算周长 就被封装在 类中了。
看下面的例子:
import math
class Point:
def __init__(self, x=0, y=0):
self.reset(x, y)
def move(self, x, y):
self.x = x
self.y = y
def reset(self, x, y):
self.x = x
self.y = y
def cal_distance(self, point):
"""
求两点之间的距离
:param point:
:return:
"""
return math.sqrt((self.x - point.x) ** 2 + (self.y - point.y) ** 2)
class Polygon:
def __init__(self):
self.vertices = []
def add_point(self, point):
self.vertices.append(point)
def perimeter(self):
perimeter = 0
points = self.vertices + [self.vertices[0]]
for i in range(len(self.vertices)):
perimeter += points[i].cal_distance(points[i + 1])
return perimeter
if __name__ == '__main__':
square = Polygon()
square.add_point(Point(1, 1))
square.add_point(Point(1, 2))
square.add_point(Point(2, 2))
square.add_point(Point(2, 1))
ret = square.perimeter()
print(f"{ret}")
Polygon 通过这个类 ,然后添加 point , 然后添加 perimeter 这个方法 。 这样写 其实 就是 把 面向过程 写的 代码 放在了 一个类中, 然后通过类中的一些 数据,然后通过实现方法来操作数据,最后 获取结果。
上面的结果 和上面面向过程的结果是一样的。
你可能有疑问了? 面向对象的写法 ,把代码写多了,没有什么呀?
其实不然, 其实在写代码,最终要给你人来看的, 后期要考虑维护成本。面向对象 的方式 首先 本身 就是具有描述行为的,比如 Point
类,本身代表了一个点,大家一个就能知道。
但是 如果按照面向过程中 定义一个list square = [(1, 1), (1, 2), (2, 2), (2, 1)]
我相信 如果过了一个月后 ,你再看 square 这个东西,你可能不理解 我这里写的 元祖 里面的数字 代表什么意思?
看到了吗, 这就是区别,在面向对象的思想中 代码的可读性 更强,可维护更强。
通过上面的例子 你应该大概理解了面向对象思考过程。 对象 其实就是一个封装, 对象 是 数据和行为的一个集合,对象中的属性 我一般喜欢叫数据,方法 就是用来来操作这些数据的。
对象 本身的行为 叫 方法 。
以我举个例子, 比如我现在 要封装一个我这个类,我有一个方法 叫做饭,吃饭,还有一个方法叫游泳 。
我中还有一些属性, 姓名 ,身高,体重。
class Person:
def __init__(self, name, height, weight):
self.name = name
self.height = height
self.weight = weight
person = Person(name='frank', height=165, weight=55)
这里 就是通过 Person
来创建了一个对象 , Person(name='frank', height=165, weight=55)
这里 的意思 就是 调用了 __init__
方法 , 把三个属性拷贝到了 person 的对象上面。
>>> person = Person(name='frank', height=165, weight=55)
>>> person.name
'frank'
>>> person.height
165
>>> person.weight
55
现在 你已经掌握了如何创建一个对象的方法。 你可能 会有疑问 为啥 __init__()
方法里面 为啥会有self 参数,其实这个self 就是你将来 赋给的那个对象,这个self 你就可以这样理解。 这里 self 就相当于 你创建每创建一个新的对象,它就会指向这个对象。
person = Person(name='frank', height=165, weight=55)
比如这里 self 就代指 person .
现在 来继续实现一些方法
这里只是举例, 假设 eat 后 我体重会重, 游泳后,我体重会变轻。
class Person:
def __init__(self, name, height, weight):
self.name = name
self.height = height
self.weight = weight
def cook(self):
print(f"{self.name} is cooking")
def eat(self):
print(f"{self.name} is eating")
self.weight = self.weight + 2
def swim(self):
print(f"{self.name} is swimming")
self.weight = self.weight - 1
>>> person.name,person.height,person.weight
('frank', 165, 55)
>>> person.cook()
frank is cooking
>>> person.eat()
frank is eating
>>> person.weight
57
>>> person.eat()
frank is eating
>>> person.weight
59
>>> person.swim()
frank is swimming
>>> person.swim()
frank is swimming
>>> person.weight
57
看上面的例子 ,当我吃饭的 时候 体重就会变重,游泳体重就会下降。这就是 面向对象 编程。
类 是用来 描述对象的。 它们就像用来创造对象的蓝图。 类相当于 是一个 模板 这个模板来创建一个对象。
类是对象的一个抽象,对象 就是一个具体的
类,对象 就是由类 创建出来的。
class Person:
def __init__(self, name):
self.name = name
p = Person(name='frank')
lily = Person(name='lily')
上面 定义Person 类,然后 由类 生成一个对象 p 和一个对象 lily 。 这一个对象 创建了两个对象。
程序员 就是 每天都要面对很多对象,整天和这些对象打交道。
对象随时有,只要你肯new。
你看程序员 没有对象是不可能的,每天都和很多对象打交道。
简单总结:
我们通过方法 来实现不同的功能,属性 就是 对象中的一些 数据, 通过 方法 可以操作这些数据,来完成一些操作 这就是面向对象编程。
面向对象编程的好处 有哪些呢?
第一代码比较清晰,通过名称 大概知道 是做什么。
第二 代码 复用性更强, 因为 类是可以继承的。(以后会讲到)
第三 更加 方便的维护 一些比较大的项目。
这篇 文章 主要简单介绍了面向对象的基础知识,了解面向对象思想。之后我会在写一下 更好的使用面向对象的思想 进行编程 。 好了,有了这篇文章,你可以尝试一下 把一些函数 变成一个类中的方法,改成面向对象的代码。然后来感受一下,不同的编程方法。