设计教室
设计欣赏|图形图像|媒体动画|机械电子|CI设计|设计文献|PhotoShop|Corel3Dmax|Flash|AutoCad|设计视频
首页 > 设计教室 > 机械电子 > MATLAB > 正文

Matlab 面向对象编程


8.9 面向对象编程
8.9.2 面向对象编程应用示例

【例 8.9.2 -1 】本例演示:创建“先进先出” FIFO 队列 queue 类的全过程。在本例中,读者应充分注意:构架域( Fields of a structure array )和定义在其上的方法函数( Method function )之间的关系。

(1)建立类目录 @queue
(2)选择构架数组为 queue 类的数据结构
(3)创建构造函数 queue.m
[@queue/queue.m]
function q=queue(v)
%@QUEUE/QUEUE queue class constructor function
% 调用格式
% q=queue 创建一个 " 空 " 队列对象 .
% q=queue(v) 创建包含变量 v 的队列对象。
superiorto( 'double' , 'sparse' , 'struct' , 'cell' , 'char' , 'inline' , 'sym' );
% 使 queue 对象具有最高优先级 <6>
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
q.value=[]; % value 域被赋“空阵”
q.name= '' ; % name 域不给任何字符
q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签
elseif isa(v, 'queue' ); % 输入宗量是同类对象情况
q=v; % 直接把输入量赋给 q
else % 非同类输入宗量情况
q.value=v; % 在 value 域中放置输入对象 v 的内容
q.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(q.name) % 假如输入量无名
q.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end

q=class(q, 'queue' ); % 给变量 q 挂上 queue 标签 <20>
end

(4)为 queue 对象编写显示函数 display.m
[@queue/display.m]
function display(q,ki,kj)
%QUEUE/DISPLAY command window display of a queue object.
% 调用格式
% display(q) 笼统显示整个队列
% display(q,ki) 单下标法显示具体队列元素的内容
% display(q,ki,kj) 双下标法显示具体队列元素的内容
if nargin==0;error( ' 缺少输入宗量,即被显示对象 ! ' ); end
switch nargin
case 1 % 显示整个队列
[m,n]=size(q);
vname=inputname(1); % 被显示对象 q 的名称
if isempty(vname) % 显示对象若无名称
fprintf( 'ans=/n' ); % 按 MATLAB教程: 惯例,屏幕显示 ans 缺省名
elseif fprintf( '%s=/n' ,vname); % 对象有名称时,则屏幕以字符串形式显示名称
end ;

if isempty(q) % 假如被显示对象为“空”
fprintf( ' [ empty ' ) %<17>
fprintf( '%s' ,class(q)) %<18>
fprintf( ' ]/n/n' ); %<19>
elseif m*n==1; % 被显示对象今包含一个“元素”时
fprintf( ' %s: ' ,q.name); % 屏幕先以字符串形式显示所存放对象的名称
disp(q.value); % 紧接着,不换行,显示所存放对象的内容
fprintf( '/n' );
else % 被显示对象今包含多个“元素”时
fprintf( ' [ %d*%d ' ,m,n) % 以下 3 条指令只显示队列“元素”排列 <25>
fprintf( '%s' ,class(q)) %<26>
fprintf( ' ]/n/n' ); %<27>
end

case 2 % 单下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ')' ])
disp([ 'is a ''' ,class(q(ki).value), ''' object' ])
fprintf( ' %s=/n' ,q(ki).name);
disp(q(ki).value);
fprintf( '/n' );
case 3 % 双下标法显示具体队列元素的内容
disp([ 'The content of ' ,inputname(1), '(' ,int2str(ki), ',' ,int2str(kj), ')' ])
disp([ 'is a ''' ,class(q(ki,kj).value), ''' object' ])
fprintf( ' %s=/n' ,q(ki,kj).name);
disp(q(ki,kj).value);
fprintf( '/n' );
end

(5)编写重载函数 isempty.m
[@queue/isempty.m]
function f=isempty(q)
%@QUEUE/ISEMPTY True for an empty queue object.
f=0;
[m,n]=size(q);
if m*n==1;
if isempty(q.value) & isempty(q.name) %<6>
f=1;
end ;
end ;

(6)编写“入队”、“离队”函数
[ @queue/comein.m]
function q=comein(p,varargin)
% @QUEUE/COMEIN a variable comes to the end of a queue.
% 调用格式
% comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列,
% 其名沿用 p 位置上的输入队列名 .
% q=comein(p,a,b,...) 使输入宗量 a,b 等排在 p 之后形成新队列 q .
if nargin<2 error( 'comein needs at least two arguments.' ); end ;
if ~isa(p, 'queue' ) error([inputname(1), ' is not a queue' ]); end ;
q0=p;
qzzy=class(p); % 获取第一输入宗量的类别字符串 <10>
for i=1:length(varargin)
temp=varargin{i};
s=eval([qzzy, '(temp)' ]); % 使后来元素成为与第一输入宗量相同的类别 <13>
s.name=inputname(i+1);
if isempty(s.name) % 假如某输入宗量本身无名称
s.name=[ '(' class(temp) ')' ]; % 则把它的类别名作为名称使用
end

if isempty(q0) % 假如前队列是“空”队列
q0=s; % 则直接进入队列
else % 假如前队列非“空”
q0=[q0 s]; % 则新变量排在队尾
end
end

if nargout==0; % 假如没有输出宗量
assignin( 'caller' ,inputname(1),q0); % 新队列沿用第一个输入队列名
evalin( 'caller' ,inputname(1));
else % 假如有输入输出宗量
q=q0; % 新队列名为 q
end

[@queue/goout.m]
function [n,v,q]=goout(p)
% @QUEUE/GOOUT removes the first(the front) element from a queue.
% 调用格式
% goout(p) 从队列 p 中的第一个元素离队 .
% v=goout(p) v 是从 p 队列中移出的那第一个元素的“值”
% [n,v]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% [n,v,q]=goout(p) n,v 分别 是从 p 队列中移出的那第一个元素的“名称”和“值”
% q 是被移去第一个元素后的新队列
if nargin==0 ;error( 'No queue specifide.' ); end ;
if nargout>3;error( 'Too many output arguments.' ); end ;
if nargin>1 error( 'Too many input arguments.' ); end ;
if ~isa(p, 'queue' );error([inputname(1), ' is not a queue.' ]); end ;
if isempty(p)
q1=p;
else
[m,n]=size(p);
v1=p(1).value;n1=p(1).name;
if m*n==1
q1=queue;
else
q1=p(2:end);
end
end

if nargout<3;
assignin( 'caller' ,inputname(1),q1);
end ;

if nargout==0,
evalin( 'caller' ,inputname(1));
end
if nargout>=1;v=v1; end ;
if nargout>=2;n=n1; end ;
if nargout==3;q=q1; end ;

【 * 例 8.9.2 -2 】本例的目的:一,检验例 8.9.2-1 所编写的程序的正确性;二,演示所设计的新类是如何被运作的。

(1)创建一个队列对象,并显示。
qe='Hello! 你好 ! '; % 字符串
Q=queue(qe) % 生成队列对象 Q ,并显示
Q=
qe: Hello! 你好 !

(2)类别检查和是否对象判断
class(Q) % 类别检查
isobject(Q) % 是否对象判断
isa(Q,'queue') % 是否队列判断
ans =
queue
ans =
1
ans =
1

(3)是否“空”队列判断
isempty(Q)
ans =
0

【 * 例 8.9.2 -3 】本例目的:一,演示“入队”、“离队”函数的调用方法;二,演示 @queue/display 显示队列具体元素细节的功能。

(1)利用“入队”函数,使队列变长。
a=[1,2,3;4,5,6];b{1}='This';b{2}=' is ';b{3}='a cell array';
comein(Q,a,b) % 增长队列,并显示整个队列的“宏观”情况
Q=
[ 1*3 queue ]

(2)显示队列 Q 中具体元素的内容
display(Q,2) % 给出 Q 队列第 2 个元素的类别、内容:变量名和值
The content of Q(2)
is a 'double' object
a=
1 2 3
4 5 6

(3)把 Q 队列第 1 个元素和其余部分分离,并生成新队列 QQ
[nn,vv,QQ]=goout(Q)
nn =
qe
vv =
Hello! 你好 !
QQ=
[ 1*2 queue ]

(4)采用双下标法,显示 QQ(1,2) 的内容
display(QQ,1,2)
The content of QQ(1,2)
is a 'cell' object
b=
'This' ' is ' 'a cell array'

【例 8.9.2 -4 】利用指令 methods 可以获知对任何类定义的(在类目录上的)所有方法函数。
methods queue
Methods for class queue:

comein display goout isempty queue


8.9.4 继承性及其应用
8.9.4.3 利用继承性创建子类的示例

【例 8.9.4 .3-1 】把例 8.9.2-1 构成的队列作为父类,利用继承性,创建 stack 堆栈子类。
(1)建立类目录 @stack ,并使它成为当前目录 (以下指令仅对 5.3 版适用)
mkdir('e:/mat53/work','@stack') % 在 e:/mat53/work 上建子目录 @stack
cd e:/mat53/work/@stack % 是子目录 @stack 成为当前目录

(2)编写堆栈类的构造函数 @stack/stack.m
[@stack/stack.m]
function ST=stack(v)
% 调用格式
% ST=stack 创建一个 " 空 " 堆栈对象 .
% ST=stack(v) 创建包含变量 v 的堆栈对象。
if nargin>1;error( 'Too many arguments.' ); end ;
if nargin==0 % 没有输入宗量情况
Q=queue;
s.value=[]; % value 域被赋“空阵”
s.name= '' ; % name 域不给任何字符
elseif isa(v, 'stack' ); % 输入宗量是同类对象情况
s=v; % 直接把输入量赋给 q
Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
else % 非同类输入宗量情况
s.value=v; % 在 value 域中放置输入对象 v 的内容
s.name=inputname(1); % 在 name 域中放置输入对象名 v 字符
if isempty(s.name) % 假如输入量无名
s.name=[ '(' class(v) ')' ]; % 就采用 v 本身的类名
end

Q=queue(evalin( 'caller' ,inputname(1))); % 生成队列对象
end
ST=class(s, 'stack' ,Q); % 产生继承父类对象 Q 性质的 ST 堆栈子类

【 * 例 8.9.4 .3-2 】本例目的之一是:检查上例构造函数设计的正确性。目的之二是:观察堆栈关于队列的显示,类别判断和为 “空”判断性质的继承。

(1)堆栈对象的创建,及由于继承性,而获得正确显示。
AA=' 继承性 ';
ST=stack(AA)
ST=
AA: 继承性

(2)类别检查
class(ST)
ans =
stack

(3)由于在此设计采用了继承性,所以“是堆栈,就一定是队列”。
isa(ST,'stack')
isa(ST,'queue')
ans =
1
ans =
1

(4)检查对 isempty.m 是被继承
isempty(ST)
ans =
0

上一篇: Matlab 图形对象的操作
下一篇:Matlab API应用程序接口

评论  点击查看
 
设计频道推荐
设计热点文章