本文的主要内容如下:
- 类声明的格式,包括属性、方法
- 类的显示方法,自定义disp输出
面向对象编程的有点我就不讲了,直接介绍如何声明和使用类。
首先举一个例子,假设我要定义一个二维平面上的点叫 Point,这是一个类,这个类包含两个属性,x轴坐标和y轴坐标,然后可以包含一个归一化的方法,使其转换成单位圆上的点,那么定义的代码如下:
classdef Point < handle
properties
x
y
end
methods
function normalize(obj)
r = sqrt(obj.x^2+obj.y^2);
obj.x = obj.x/r;
obj.y = obj.y/r;
end
end
end
properties 下面声明类的属性,methods 下面是类里面的方法(函数),下面我们看具体使用。
-
属性访问
a = Point() 实际上就是声明一个 Point 对象名称为 a,这个时候我们并没有对a中的两个属性 x和y赋值,因此初始值为空。 我们可以使用点来访问对象中的元素并进行赋值:
-
一般函数调用
在上面的代码中我们定义了一个公用函数 normalize(),可以像访问属性一样使用。
-
构造函数
使用构造函数可以方便我们对对象进行初始化,在未自定义构造函数的时候,像最上面一样会默认都为空,我们对上面的代码进行一些修改如下:
classdef Point < handle
properties
x
y
end
methods
function normalize(obj)
r = sqrt(obj.x^2+obj.y^2);
obj.x = obj.x/r;
obj.y = obj.y/r;
end
function obj = Point()
obj.x = 0;
obj.y = 0;
end
end
end
此处的Point()就是我们自己定义的构造函数,当我们声明一个Point对象的时候,会被初始化为 x = y =0,如下图所示:
我们还可以定义更为复杂的构造函数,来实现需要的功能,下面的代码可以直接初始化成我们想要的点。
classdef Point < handle
properties
x
y
end
methods
function normalize(obj)
r = sqrt(obj.x^2+obj.y^2);
obj.x = obj.x/r;
obj.y = obj.y/r;
end
function obj = Point(x,y)
obj.x = x;
obj.y = y;
end
end
end
- 对象的自定义disp函数
当我们没有在语句后面加上 ; 的时候,像上面的图片那样,会显示对象的内容,其实这是调用了disp函数,观察下面的代码:
如果说对象的结构比较复杂,我们并不想这样输出,或者不想将所有的属性都显示出来就可以使用自定义的disp函数,如下:
classdef Point < handle
properties
x
y
end
methods
function normalize(obj)
r = sqrt(obj.x^2+obj.y^2);
obj.x = obj.x/r;
obj.y = obj.y/r;
end
function obj = Point(x,y)
obj.x = x;
obj.y = y;
end
function disp(obj)
disp('------------------');
s = sprintf('坐标为(%3.3d,%3.3d)\n',obj.x,obj.y);
disp( [s 'obj.disp was called.'])
end
end
end
这说明在显示对象的时候其实是调用了 一个默认的disp函数,我们可以通过自定义来格式化输出。
- 成员方法和构造函数的区别
1.输入参数不同
在构造函数中,是没有输入参数的,但是在成员方法中,一定至少需要一个输入参数obj用来表示对象,这也就决定了我们无法直接调用构造函数,而只能调用成员方法。
注意,在没有其他输入参数的时候可以省略括号。
2. 返回值不同
构造函数返回值是一个对象,但是成员方法返回值可以根据自己的需求更改,或者没有返回值。
hint:
调用成员函数有两种方式,一种是 function(obj),另一种是obj.function,这两种方法得到的效果是一样的,但是一般推荐使用后一种,更加明确一点,实际上后面的一种方法中前面的obj是一个输入参数,因此我们在定义成员函数的时候即使没有要使用的输入参数也要有一个obj表示调用函数的对象。