复制子类对象的超类部分



假设我有

classdef A < matlab.mixin.Copyable & matlab.mixin.Heterogeneous
.
.
classdef B < A
.
.
classdef C < A

我想要的是能够在B的实例的基础上构建C的实例,只复制A属性。我宁愿不实现自定义的mycopy方法,因为每次向a.添加属性时都需要更新它

我尝试修改B的copyElement(),使其只调用A的copyElement(),但(毫不奇怪)仍然返回了B类的对象。

请注意,我的"转换"与大多数问题(SO和Google)的方向相反,这些问题从超类复制到子类。也许出于某种概念上的原因,我想要的是一个坏主意。尽管如此,正如这里所说的

类设计中的一个重要概念是,子类对象也是其超类的对象。

我知道我可以从超类对象构造一个子类对象。

注意:如果你需要这样做,使得"C"不是"B"的子类,那么跳过"C"的第一个版本,并在最后签出"C2"类。

我为复杂超类的复杂子类制定了这个复制数据的解决方案,并想与大家分享。它适用于具有许多隐藏属性的类。我对它进行了修改,以包含您的子类和您的特定问题,所以我希望它在这两种情况下都有帮助。

因此,如果你定义一个简单的超类"a":

classdef A
    properties
        propA
        propB
    end
    properties (Dependent)
        dependentProp;
    end
    methods
        function val=get.dependentProp(obj)
            val='dependent value';
        end
    end
end

然后,您可以为子类"B"提供一个构造函数,以查找和复制所有自变量(查看有关属性的信息,以了解有关"?"运算符和属性元数据的更多信息):

classdef B < A
    properties
        propI
        propJ
    end
    methods
        function obj=B(varargin)
            obj@A();
            if nargin==1
                if isa(varargin{1},'A')
                    meta=?A;
                    dependent=[meta.PropertyList.Dependent];
                    props={meta.PropertyList.Name};
                    for pname=props(~dependent)
                        eval(['obj.' pname{1} '=varargin{1}.' pname{1} ';']);
                    end
                end
            end
        end
    end
end

通过这样做,您可以从类"a"的对象创建类型"B"的对象:

objA=A;
objA.propA='valA';
objA.propB='valB'
objB=B(objA)

这将产生以下输出:

objA = 
  A with properties:
        propA: 'valA'
        propB: 'valB'
    dependentProp: 'dependent value'

objB = 
  B with properties:
        propI: []
        propJ: []
        propA: 'valA'
        propB: 'valB'
    dependentProp: 'dependent value'

最后,要处理"C"类,只需调用"B"类的构造函数即可,而无需添加任何附加代码:

classdef C < B
    properties
        propM
        propN
    end
    methods
        function obj=C(varargin)
            obj@B(varargin{:});
        end
    end
end

然后,您可以从类"B"的对象创建类"C"的对象,只需复制类"A"的值:

objC=C(objB)

产生所需结果:

objC = 
  C with properties:
            propM: []
            propN: []
            propI: []
            propJ: []
            propA: 'valA'
            propB: 'valB'
    dependentProp: 'dependent value'

然而,如果类"C"是"a"的子类,而不是"B"的子类别(如OP中所示),则应将其定义为

classdef C2 < A
    properties
        propM
        propN
    end
    methods
        function obj=C2(varargin)
            obj@A();
            if nargin==1
                if isa(varargin{1},'B')
                    meta=?A;
                    dependent=[meta.PropertyList.Dependent];
                    props={meta.PropertyList.Name};
                    for pname=props(~dependent)
                        eval(['obj.' pname{1} '=varargin{1}.' pname{1} ';']);
                    end
                end
            end
        end
    end
end

然后,

objC2=C2(objB)

将导致

objC2 = 
  C2 with properties:
            propM: []
            propN: []
            propA: 'valA'
            propB: 'valB'
    dependentProp: 'dependent value'

如果这对你有用,请告诉我。

注意:如果您的超类中有禁用了set方法的属性,则可能需要更新构造函数以从正在设置的属性中排除这些方法。

另请注意:如果您在超类中为因变量设置了方法,并且需要在构造函数中设置它们,那么您也必须解决这个问题。

最新更新