mirror of
https://github.com/jaywcjlove/reference.git
synced 2025-06-16 20:21:22 +08:00
doc: update docs/matlab.md (#969)
This commit is contained in:
396
docs/matlab.md
396
docs/matlab.md
@ -1410,6 +1410,402 @@ true 或 false 条件
|
|||||||
[thingSpeakWrite](https://ww2.mathworks.cn/help/matlab/ref/thingspeakwrite.html) | 将数据写入 `ThingSpeak` 通道
|
[thingSpeakWrite](https://ww2.mathworks.cn/help/matlab/ref/thingspeakwrite.html) | 将数据写入 `ThingSpeak` 通道
|
||||||
<!--rehype:className=style-list-->
|
<!--rehype:className=style-list-->
|
||||||
|
|
||||||
|
## 面向对象基础
|
||||||
|
|
||||||
|
MATLAB 支持面向对象编程,虽然很少有人使用。
|
||||||
|
|
||||||
|
MATLAB 的自定义类型可以分成全值类和句柄类,它们的区别在于句柄类相当于指针,赋值时只会进行浅拷贝,全值类总是会进行深拷贝。下面的例子只涉及全值类。
|
||||||
|
|
||||||
|
### 简单例子
|
||||||
|
|
||||||
|
一个简单的 `point2d` 类(文件名必须与类名相同:`point2d.m` )
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef point2d
|
||||||
|
properties % 属性
|
||||||
|
x
|
||||||
|
y
|
||||||
|
end
|
||||||
|
methods % 方法
|
||||||
|
function obj = point2d(x0,y0) % 构造方法
|
||||||
|
if nargin == 0
|
||||||
|
obj.x = 0;
|
||||||
|
obj.y = 0;
|
||||||
|
elseif nargin == 2
|
||||||
|
obj.x = x0;
|
||||||
|
obj.y = y0;
|
||||||
|
else
|
||||||
|
error("unsupported arguments")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function obj = normalize(obj) % 普通方法
|
||||||
|
% obj 相当于 Python 的 self
|
||||||
|
r = sqrt(obj.x^2+obj.y^2);
|
||||||
|
obj.x = obj.x/r;
|
||||||
|
obj.y = obj.y/r;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
使用例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
a = point2d(3,4);
|
||||||
|
fprintf('(%f, %f)\n',a.x,a.y);
|
||||||
|
% (3.000000, 4.000000)
|
||||||
|
|
||||||
|
b = a.normalize();
|
||||||
|
fprintf('(%f, %f)\n',b.x,b.y);
|
||||||
|
% (0.600000, 0.800000)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 属性
|
||||||
|
|
||||||
|
可以给属性提供默认值
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef point2d
|
||||||
|
properties
|
||||||
|
x = cos(pi/12);
|
||||||
|
y = sin(pi/12);
|
||||||
|
end
|
||||||
|
...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
默认值不需要是常量,可以是任何表达式
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties
|
||||||
|
time_stamp = date;
|
||||||
|
end
|
||||||
|
...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
属性的默认值在类被加载时会被计算,并不会在每一个对象创建时重新计算。
|
||||||
|
|
||||||
|
可以将属性标记为只读(`Constant`),不允许对其进行修改。
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties(Constant)
|
||||||
|
R = pi/180;
|
||||||
|
end
|
||||||
|
...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
尝试修改会报错
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
s = demo();
|
||||||
|
disp(s.R)
|
||||||
|
|
||||||
|
s.R = 100; % error
|
||||||
|
```
|
||||||
|
|
||||||
|
### 构造方法和普通方法
|
||||||
|
|
||||||
|
#### 构造方法
|
||||||
|
|
||||||
|
与类同名的方法称为构造方法。MATLAB只允许创建一个构造方法,但是我们通过nargin判断参数个数,并据此实现不同的创建行为,例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
function obj = point2d(x0,y0)
|
||||||
|
if nargin == 0
|
||||||
|
obj.x = 0;
|
||||||
|
obj.y = 0;
|
||||||
|
elseif nargin == 2
|
||||||
|
obj.x = x0;
|
||||||
|
obj.y = y0;
|
||||||
|
else
|
||||||
|
error("unsupported arguments")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
s1 = point2d(1,2);
|
||||||
|
s2 = point2d();
|
||||||
|
s3 = point2d;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 普通方法
|
||||||
|
|
||||||
|
类的普通方法的第一个参数是对象自身,并且习惯上使用obj表示。
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties
|
||||||
|
x = 100;
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function z = compute(obj,y)
|
||||||
|
z = obj.x + y;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
普通方法可以通过对象或类调用
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
s = demo();
|
||||||
|
s.compute(10); % 110
|
||||||
|
compute(s,20); % 120
|
||||||
|
```
|
||||||
|
|
||||||
|
### 静态方法
|
||||||
|
|
||||||
|
MATLAB 提供了静态方法,在定义时标记为 `Static`,静态方法没有`obj`参数,不绑定任何的对象,不能访问类对象的普通属性,但是可以访问类的常量属性。
|
||||||
|
|
||||||
|
例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
methods(Static) % 静态方法
|
||||||
|
function hello()
|
||||||
|
disp("hello,world!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
使用例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
>> demo.hello()
|
||||||
|
hello,world!
|
||||||
|
>> s = demo();
|
||||||
|
>> s.hello()
|
||||||
|
hello,world!
|
||||||
|
```
|
||||||
|
|
||||||
|
### 重写disp方法
|
||||||
|
|
||||||
|
可以通过提供`disp`方法来定制自定义类型调用`disp`函数时的行为,例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef point2d
|
||||||
|
properties
|
||||||
|
x = 0
|
||||||
|
y = 0
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function disp(obj)
|
||||||
|
fprintf("(%f,%f)",obj.x,obj.y);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
提供`disp`函数后的输出
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
>> s = point2d();
|
||||||
|
>> disp(s)
|
||||||
|
|
||||||
|
(0.000000,0.000000)
|
||||||
|
```
|
||||||
|
|
||||||
|
作为对比,默认情况下的输出
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
>> s = point2d();
|
||||||
|
>> disp(s)
|
||||||
|
point2d with properties:
|
||||||
|
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
R: 0.0175
|
||||||
|
```
|
||||||
|
|
||||||
|
### 重载运算符
|
||||||
|
|
||||||
|
MATLAB 支持自定义类型对运算符的重载,例如`plus`方法对应加法。
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef point2d
|
||||||
|
properties
|
||||||
|
x
|
||||||
|
y
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function obj = point2d(x0,y0)
|
||||||
|
% same as before
|
||||||
|
end
|
||||||
|
function result = plus(obj, other)
|
||||||
|
result = point2d(obj.x + other.x, obj.y + other.y);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
>> a = point2d(1,0);
|
||||||
|
>> b = point2d(0,2);
|
||||||
|
>> a + b
|
||||||
|
ans =
|
||||||
|
point2d with properties:
|
||||||
|
|
||||||
|
x: 1
|
||||||
|
y: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### 属性和方法的权限
|
||||||
|
|
||||||
|
MATLAB 提供了比 C++ 和 Java 更加精细的访问权限控制,默认情况下所有的属性和方法都是public。
|
||||||
|
|
||||||
|
基本的三种权限例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties % public
|
||||||
|
x1
|
||||||
|
end
|
||||||
|
properties(Access = protected)
|
||||||
|
x2
|
||||||
|
end
|
||||||
|
properties(Access = privated)
|
||||||
|
x3
|
||||||
|
end
|
||||||
|
|
||||||
|
methods % public
|
||||||
|
function h1(obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
methods(Access = protected)
|
||||||
|
function h2(obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
methods(Access = privated)
|
||||||
|
function h3(obj)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
MATLAB对属性提供了更精细的访问权限,可以将其拆分为读权限和写权限,例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties(SetAccess = private)
|
||||||
|
x1
|
||||||
|
end
|
||||||
|
properties(SetAccess = private, GetAccess = protected)
|
||||||
|
x2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### 类的继承
|
||||||
|
|
||||||
|
MATLAB 使用 `<` 表示继承关系。
|
||||||
|
|
||||||
|
基类
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
properties
|
||||||
|
Value
|
||||||
|
end
|
||||||
|
methods
|
||||||
|
function obj = demo(val)
|
||||||
|
if nargin > 0
|
||||||
|
obj.Value = val;
|
||||||
|
else
|
||||||
|
obj.Value = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function displayValue(obj)
|
||||||
|
disp(['Value: ', num2str(obj.Value)]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
派生类
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo2 < demo
|
||||||
|
properties
|
||||||
|
ExtraValue
|
||||||
|
end
|
||||||
|
|
||||||
|
methods
|
||||||
|
function obj = demo2(val, extraVal)
|
||||||
|
obj = obj@demo(val); % 调用基类构造方法
|
||||||
|
if nargin > 1
|
||||||
|
obj.ExtraValue = extraVal;
|
||||||
|
else
|
||||||
|
obj.ExtraValue = 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function displayValue(obj)
|
||||||
|
displayValue@demo(obj); % 调用基类的同名函数
|
||||||
|
disp(['Extra Value: ',num2str(obj.ExtraValue)]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
### 补充
|
||||||
|
|
||||||
|
#### 抽象方法和抽象类
|
||||||
|
|
||||||
|
MATLAB提供了抽象方法和抽象类。
|
||||||
|
|
||||||
|
抽象基类(不可实例化)
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
methods(Abstract) % 抽象方法
|
||||||
|
hello(obj) % 只有接口,没有实现
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
继承自抽象基类的派生类(实现了抽象方法,可以实例化)
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo2 < demo
|
||||||
|
methods
|
||||||
|
function hello(obj) % 实现抽象方法
|
||||||
|
disp("hello,world!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 禁止继承和重写
|
||||||
|
|
||||||
|
可以使用 `Sealed` 关键词来禁止一个类被继承,例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef (Sealed) demo
|
||||||
|
...
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
可以使用 `Sealed` 关键词来禁止方法被派生类重写,例如
|
||||||
|
|
||||||
|
```matlab
|
||||||
|
classdef demo
|
||||||
|
methods(Sealed)
|
||||||
|
...
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
另见
|
另见
|
||||||
----
|
----
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user