在MATLAB中覆盖超类方法和访问修饰符

11
考虑以下简单的类层次结构:

A.m

classdef A < handle
    methods (Access = protected)    %# protected vs. private
        function foo(obj)
            disp('class A')
        end
    end
end

B.m

classdef B < A
    methods (Access = public)
        function foo(obj)
            disp('class B')
        end
    end
end

类B继承自类A,应该将受保护的foo方法重写为公共方法。

如果我们尝试实例化派生类,则会出现以下错误:

>> b=B();
Error using B
Method 'foo' in class 'B' uses different access permissions than its superclass 'A'. 

奇怪的是,如果foo在父类A中被定义为私有方法,则当我们调用重写方法时,代码也能正常工作:

>> clear classes
>> b=B(); b.foo()
class B

这是MATLAB面向对象实现的一个限制/bug,还是这种行为背后有充分的理由?(代码在R2012b上测试过)
相比之下,在Java中,规则规定您不能在子类中减少方法的可见性,但可以增加可见性,其中:
(weakest) private < package < protected < public (strongest)

你有联系过TMW吗?看起来像是一个bug... - Rody Oldenhuis
@RodyOldenhuis:还没有,我不确定这是MathWorks的一个错误还是设计选择。 - Amro
1个回答

11

这似乎是Matlab的一个限制。我已经尝试了所有属性组合,除非A中的方法是私有的,否则当B中的属性不同时,Matlab会抛出错误。

enter image description here

换句话说,除非A中的方法是私有的,否则A和B中方法的属性必须相同。从某种程度上说,这似乎是有道理的,因为TMW表示:“如果子类可以看到一个方法,那么属性必须相同;如果子类看不到一个方法,子类可以做任何它们想要做的事情。”


谢谢@Jonas,我也尝试了所有这些情况...从设计角度来看,我认为没有理由不允许覆盖方法(你图中的下三角应该都是笑脸!)。毕竟,Java让我们增加访问权限,就像我之前解释的那样,C#提供了overridenew关键字来允许覆盖与隐藏,而C++在这方面几乎没有限制..这是MathWorks需要考虑的事情 :) - Amro
@Amro 是的,但人们意识到C++的限制性有些过少,因此出现了关于如何正确使用C++的书籍。请注意,最后一行中的笑脸与继承无关,因为B看不到A的私有方法。此外,如果将A的受保护部分公开,则会破坏A的设计约束,B也不再是一个A。 - Barney Szabolcs
@BarnabasSzabolcs:没有异议。至于最后一点,我想解决方法很简单;在B中添加第二个公共方法foo_public,调用其受保护的foo而不会破坏继承接口。 - Amro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接