本节书摘来华章计算机《交互式程序设计 第2版》一书中的第2章 ,第2.6节,Joshua Noble 著 毛顺兵 张婷婷 陈宇 沈鑫 任灿江 译更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.6 对象和属性

对象是什么?对象是将多个属性集中在一起、代表所有这些不同属性的东西。听起来挺抽象的是不?其实很简单,就拿一把椅子打个比方。一把椅子有它的高度、重量,还有若干椅子腿。好,这里就有三个属性了,它们都属于一种叫做“椅子”的东西。写成代码就是这样:

Chair myChair; 
myChair.height = 22;

看到Chair实例的名字和属性之间的那个点(.)吗?那是点操作符。在现有流行的编程语言中,常用点操作符访问、使用和设置对象的属性。我们继续对椅子做些事情:

myChair.legs = 4; 
myChair.weight = 5;

现在你制作了一把名叫“myChair”的椅子,它有若干属性:椅子腿、重量和高度。做椅子有点无聊吧,那么我们来看些实用的例子。以下是一段Processing代码。

PImage img = loadImage("mypicture.jpg"); 
image(img, 20, 10); 
img.x = 300; // 设置图像在x轴上的位置 
img.y = 300; // 设置图像在y轴上的位置

上面这几行代码初看让人迷惑,其实细看就很快能明白的。PImage是Processing里的一个对象,用于加载和显示图像文件,还可以调整图像尺寸以及处理图像的像点。下一章我们讲Processing的时候会对此进行详细解释,现在你只需要看最后的两行:

img.x = 300; // 设置图像在x轴上的位置 
img.y = 300; // 设置图像在y轴上的位置

这两行就是说,PImage有一个名为x的属性和一个名为y的属性。当你创建了一个PImage对象,就是上面代码里的img,就可以获得或者设置这些属性。你可以告诉对象图像应该放在哪个位置,也可以获取图像的位置,就看你把img放在等号的哪一边了。

int xPosition = img.x; // 获取图像在x轴上的位置 
img.x = 400; // 设置图像在x轴上的位置

接下来我们看看这图像还能做点别的什么,例如复制和返回它所有的像点,以便被其他图像使用。PImage用函数copy实现这个操作,我们来看看是怎么调用这个函数的:

img.copy();

又见到点操作符了。除了操作属性,点操作符还可以调用函数。的确容易混乱,但这样挺方便的。这个点告诉你正在使用对象内部的东西。所以PImage的函数copy也可以理解为PImage的一个属性,只是它以函数的方式存在而已。
注意: 方法和函数:当一个函数作为某物的一部分时,这个函数就是一个“方法”,例如copy就是PImage的一个方法。它们几乎只有字面上的差别,使用的时候完全不需要担心。只要记住,“方法”就是指属于一个对象(如PImage)的函数。
如果你碰巧点开了函数copy在Processing主页上的文档,你会见到如图2-7所示的页面。
你可以从中获得什么信息呢?它给你举了个调用PImage copy的例子,并告诉你函数签名是什么。在Processing里是这样用的:

img.copy(sx, sy, swidth, sheight, dx, dy, dwidth, dheight); 
img.copy(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);

这是告诉你PImage有一个叫copy的函数,这个函数有两种调用的方式。具体怎么调用还要继续查文档,看看分别传入的是什么参数,但仅看参数名也能猜出个大概。我们继续看图2-7所示的文档,可以发现末尾处说明格式的部分第一个函数的括号里,有些参数开头加了s,有些加了d。s表示来源,d表示目标,这样参数的意义更容易理解,也更便于记忆。这个函数把一个PImage对象的像素复制到另一个PImage对象。粗略了解函数的参数后,就可以试着用它了,用在两个不同的PImage对象上:
image

图2-7:PImage copy在Processing.org的文档

PImage p1 = loadImage("baby.jpg"); 
image(p1, 0, 0); 
PImage p2 = new PImage(400, 400); 
p2.copy(p1, 0, 0, p1.width, p1.height, 10, 10, p1.width * 2, p1.height * 2); 
image(p2, 100, 100);

仔细看看第4行。对PImage的一个实例p2调用了函数,把实例p1的高和宽作为参数传递给函数。让我们再看一次这个函数的签名。

img.copy(srcImg, sx, sy, swidth, sheight, dx, dy, dwidth, dheight);

函数从srcImg复制像素,被复制的像素处于srcImg横轴的sx位置和纵轴的sy位置,像素将被复制到目标图像的dx和dy位置,同时也指定了复制的范围大小。可以利用一个PImage实例的属性向另一个实例的函数传递参数。这是惯常的做法,用来保存、传递和获取对象的属性。
如果你制作了一个对象,这个对象包含了多个对象在内,这好比是一个有多张照片的相册。好吧,我们先把这个对象命名为PhotoAlbum。这个对象有一个名为getNewestPicture的函数。在Processing中可以这样处理PhotoAlbum类:

PhotoAlbum newAlbum; 
newAlbum.getNewestPicture().filter(BLUR);

我们还没提过filter函数,但想必你已经能猜到filter(BLUR)是做什么用的。亮点在于两个函数连续调用。其实以上两行代码等价于:

PhotoAlbum newAlbum;
PImage img = newAlbum.getNewestPicture(); 
img.filter(BLUR);

两种写法效果一样,你自己写的时候挑一种就行了,重要的是这两种写法你都能看懂。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐