面向对象
什么是面向对象
面向对象的程序设计(Object Oriented Programming,OOP)简单来说就是以对象为中心来设计和开发程序,也就是说将实现的软件需求抽象成不同的对象和对象之间的交互过程。
概念
仅本问题涉及,并非全部概念
类:类就是类别或者类型,是用来定义对象的。
对象:对象是类的实例化,是以类为模板创造出来的。
eg:公元XXXX年,我们实现了可以用AI机器人作为自己的npy,此时单身了18年的张三,想找一个npy。此时张三有自己的择偶标准1,但是却找不到完全和自己的标准一致的,所以这时候就按照自己的标准用AI机器人创造了一个自己理想中的npy2。
语法
class Npy(Object):
pass
# Npy: 类的名字(可以随便换)
# Object: 父类名字(一般用Object)
跳马问题
问题
在一个n*m的棋盘上,P点上有一个中国象棋的马,Q点为马运动的终点。规定马只能往右走,求马从P到Q的路径数
解析
- 捋清楚有哪几个对象,他们都能干些什么事情
- 智能棋盘, 棋子
- 棋盘:计算上面的棋子运动的所有路径,并找出符合要求的路径
- 棋子:运动
- 如何抽象出这些对象
- 可以用类来抽象
- 具体的某一个点可以用一组列表[x, y]来表达
- 找出路径
- 只要某一点[x, y]与终点的表达相同,那么就有一条路径符合要求。所以只要暴力枚举就能找到全部路径。
给出以下四个步骤
- 第一步:让点动起来
我们的点的的表达是[x, y],它的本质是一个列表,所以我们通过修改里面的数据达到让点动起来的效果。
eg:[0, 0] -> [1, 2] ->[2, 4]
def move(points: list, x, y):
res, lis = list(), points[:] # 保护原本的数据,防止出错
# 让点动起来
lis[0] += x
lis[1] += y
res.append(lis[:])
return res
- 然而实际棋盘是有边界的,所以我们应该加一个限制条件,防止它跳出棋盘。
def move(points: list, x, y, args: list):
res, lis = list(), points[:]
lis[0] += x
lis[1] += y
if (
((lis[0] <= args[0]) and (lis[0] >= 0))
and
((lis[1] <= args[1]) and (lis[1] >= 0))
):
res.append(lis[:])
return res
# args: 棋盘的大小,if中第一行限制棋的横坐标,第二行限制棋的纵坐标,使二者均在范围内。
- 第二步:抽象出“点”类
首先,这个点要知道自己的坐标
其次,这个点的坐标要让棋盘知道
所以得出以下代码:
class Point(Object):
# __init__方法会在一个对象创建的时候自行调用,这时候我们只需要把它的位置"告诉"它就好了(参数输入)
def __init__(self, *args):
self.args = args # 函数中的参数前加一个*就变为一个不定参,其本质为一个元组(tuple)
def givepoint(self):
return list(self.args)# "告诉"棋盘自身"位置",并将不可修改的元组变为可修改的列表,便于前文所述的让点动起来。
- 第三步:抽象出“棋盘”类
- 一个棋盘一定会有一个边界,而且这个棋盘能知道棋子的起点和终点位置
class CheckerBoard(object):
def __init__(self, *args):
self.args = args
def findpoint(self, obj1, obj2):
lis1, lis2, res = obj1.givepoint(), obj2.givepoint(), list()
res.append(lis1)
res.append(lis2)
return tuple(res)# 用元组来保证起点终点不会被修改
2.这个棋盘能计算棋子所有的可能落点