假設我們有了二維點Point類爲基類,這是我們想拓展其成爲三維點 Point2類,此時並不需要全部重新構造一個新類,而是在Point的基礎上添加需要的屬性和方法。
子類會繼承所有非私有的屬性和方法,可以直接訪問和使用,MATLAB默認的繼承方法是public,這裏我們不討論訪問權限,只講公有繼承。
在繼承中我們需要考慮的問題有:
- 新加屬性
- 新的構造函數
- 如何調用父類方法
- 如何區分同名函數
- saveobj和loadobj方法定義 (暫不講)
首先看原來的基類的定義 Point.m
Point 具有二維座標 ( x, y )
classdef Point < handle % 表示Point是繼承handle的
properties
x = 0
y = 0
end
methods
normalize(obj); % 在類外定義了
function obj = Point(x,y) % 可以使用nargin得到複雜初始化
obj.x = x;
obj.y = y ;
end
function disp(obj) % 自定義顯示方法
disp(['x:' num2str(obj.x)]);
disp(['y:' num2str(obj.y)]);
end
end
end
Point2 類具有三維座標 x y z
classdef Point2 < Point % 表示Point2是繼承Point
properties
z = 0; % 新增一個座標 z
end
methods
function obj = Point2(x,y,z)
obj = obj@Point(x,y);
obj.z = z;
end
function normalize(obj)
Q = sqrt(obj.x^2+obj.y^2+obj.z^2);
obj.x = obj.x/Q;
obj.y = obj.y/Q;
obj.z = obj.z/Q;
end
function disp(obj)
disp@Point(obj)
disp(['z:' num2str(obj.z)]);
end
end
end
·添加新屬性
Point 中已經有了x和y,只需要在Point2中添加 z即可
`子類的構造函數
子類的構造函數需要先調用父類的構造函數,obj = obj@Point(x,y); ,這裏右邊的obj表示Point返回一個obj對象,給左邊的obj賦值之後,obj是一個Point2對象,z爲空。
從上圖可以看出obj實際上是一個Point2對象。
·調用父類方法
在上面的例子中,我們在Point2的disp函數中調用了父類的disp,其調用方式爲:
父類函數名 + @ + 父類類名 + (obj,其他參數)
disp@Point(obj) 在這裏面沒有多餘的參數,所以只需要傳入obj即可。
·區分同名函數
普通函數和類方法調用方式不同,父類和子類的同名函數需要看對象是父類還是子類
需要注意的是,爲了去耦合,即子類儘量直接調用父類的函數,而不是自己重新構造函數,比如在Point2中的disp方法,就是通過Point類中的disp方法輸出xy,然後再輸出子類中的屬性 z
·