数据抽象:使我们将一个符合数据对象的使用,与该数据对象怎样由更基本的数据对象构造起来的细节隔离开。
实例:有理数的算术运算
在使用有理数运算时,我们并不关心语言底层是如何表示、实现有理数
只知道加减乘除这几个过程的接口
通过构造函数和选择函数实现算术运算
from fractions import gcd
#最大公约数
#构造函数,构造一个有理数
#返回一个有理数,分子是整数n,分母是整数d
def make_rat(n,d):
g = gcd(n,d)
return [n//g,d//g]
#选择函数
#返回有理数x的分子
def number(x):
return x[0]
#返回有理数x的分母
def denom(x):
return x[1]
#有理数加法
def add_rat(x,y):
return make_rat(number(x)*denom(y)+number(y)*denom(x),denom(x)*denom(y))
#有理数减法
def sub_rat(x,y):
return make_rat((number(x)*denom(y)-number(y)*denom(x)),denom(x)*denom(y))
#有理数乘法
def mul_rat(x,y):
return make_rat(number(x)*number(y),denom(x)*denom(y))
#有理数除法
def div_rat(x,y):
return make_rat(number(x)*denom(y),number(y)*denom(x))
def equal_rat(x,y):
return number(x)*denom(y) == number(y)*denom(x)
#打印有理数
def print_rat(x):
print('%d / %d'%(number(x),denom(x)))
实例二:矩形的运算
from math import sqrt
#ex2.2
#定义点
def make_point(x,y):
return [x,y]
#x坐标
def x_point(p):
return p[0]
#y坐标
def y_point(p):
return p[1]
#点之间的距离
def p2p_distance(p1,p2):
return sqrt((x_point(p1)-x_point(p2))**2+(y_point(p1)-y_point(p2))**2)
#构造线段
def make_segment(s,e):
return [s,e]
#选择起点
def start_segment(l):
return l[0]
#选择终点
def end_segment(l):
return l[1]
#两个点的中点
def mid_point(p1,p2):
return make_point((x_point(p1)+x_point(p2))/2.0,(y_point(p1)+y_point(p2))/2.0)
#返回线段中点
def midpoint_segment(l):
return mid_point(start_segment(l),end_segment(l))
#打印点
def print_point(p):
print('(%f,%f)'%(x_point(p),y_point(p)))
return 0
#ex2.3
#构造矩形,输入4个点,分别代表左上tl,右上tr,左下bl,右下br
def make_rec(tl,tr,bl,br):
return [p2p_distance(tl,tr),p2p_distance(tl,bl)]
#选择函数
def length(R):
return R[0]
def width(R):
return R[1]
#计算矩阵的周长
def perimeter(R):
return 2*(length(R)+width(R))
#计算矩阵的面积
def area(R):
return length(R)*width(R)
在构造矩阵时,可以通过4个点来构造矩阵,也可以利用长和宽两个线段来表示矩阵,而计算周长和面积并不关心矩阵时用什么方式表示,都是通过同样的计算过程来实现,改变矩阵的表示方法只需要修改构造函数即可。
- 数据抽象是一种构造系统的方法学,使一个程序的功能与程序所操作的数据对象的具体表示无关。例如在设计有理数系统时,可以将有理数的算术操作设计和有理数的表示分离开来。
- 数据抽象是控制复杂性的强有力工具
- 数据对象可能存在多种有用的表示方法——抽象数据的多重表示