假设我们有了二维点Point类为基类,这是我们想拓展其成为三维点 Point2类,此时并不需要全部重新构造一个新类,而是在Point的基础上添加需要的属性和方法。

子类会继承所有非私有的属性和方法,可以直接访问和使用,MATLAB默认的继承方法是public,这里我们不讨论访问权限,只讲公有继承。在继承中我们需要考虑的问题有:

  1. 新加属性
  2. 新的构造函数
  3. 如何调用父类方法
  4. 如何区分同名函数
  5. 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