【问题标题】:Difference between "OOP" and "functional" method invocation syntax [closed]“OOP”和“功能”方法调用语法之间的区别
【发布时间】:2019-10-21 23:31:08
【问题描述】:

this page 上解释inputParser 类的使用,

我们看到示例中的每个inputParser 方法调用都采用以下形式

methodname(object, arguments)

而不是

object.methodname(arguments)

例如

addRequired(p,'filename',@ischar)

而不是

p.addRequired('filename',@ischar)

其中pinputParser 的实例。

我会说这使得addRequired 的来源不清楚,而无需通过which 或在调用它之前在代码中的实例化行中搜索它。在任何情况下都可以使用addRequired 会破坏封装,这似乎与您最初引入 OOP 所希望的完全相反。

我怀疑有充分的理由牺牲可读性并以这种特殊方式编写文档。

所以我的问题是,MATLAB 中的“功能”和“OOP”语法之间有任何实际区别吗?

【问题讨论】:

  • 关于可读性的观点,但实际上 methodname(obj, args...) 实际上是规范语法,而 obj.methodname(args...) 是语法糖。这部分源于 2008 年之前基于 classdef 的类语法,根本没有提供这种语法糖。
  • 此外,我相信在文档中搜索 addRequired 等(即通过“帮助”)也会为各种类提供该函数的任何重载,因此检测适当的使用上下文应该不是问题从这个意义上说。
  • 感谢@TasosPapastylianou 对历史原因的解释。我只是添加一条评论,希望在 MATLAB 中具有决策权的人注意到,在代码审查期间,不依赖 MATLAB 可执行文件的可读性很重要,现在通常发生在浏览器(bitbucket、github)中。
  • 我已经挖掘了这个问题/答案stackoverflow.com/questions/1693429/… 而且过去似乎也存在性能问题,但现在没有。
  • @HennadiiMadan “为什么 X 的开发人员选择使用 Z 来做 Y”问题并没有真正由任何人回答,但开发人员说,所以对 SO 不是很好。此外,这个特定问题可能会被视为您表达对某些设计选择的不满,而不是实际问题。我建议您将问题的重点改为“MATLAB 中的函数式语法和 OOP 语法有什么区别?”,在这种情况下可以建议一个客观的答案。

标签: matlab oop methods syntax matlab-class


【解决方案1】:

恐怕这些语法甚至不完全等价,这可以从以下示例中了解到:

>> f = fit( (1:3).', (2:2:6).' ,'poly1')
f = 
     Linear model Poly1:
     f(x) = p1*x + p2
     Coefficients (with 95% confidence bounds):
       p1 =           2  (2, 2)
       p2 =  -6.784e-16  (-4.709e-14, 4.574e-14)
>> methods(f)
Methods for class cfit:

argnames       cfit           coeffvalues    dependnames    feval          formula        integrate      numargs        plot           probnames      setoptions     
category       coeffnames     confint        differentiate  fitoptions     indepnames     islinear       numcoeffs      predint        probvalues     type           

>> f.coeffvalues
Error using cfit/subsref (line 18)
The name 'coeffvalues' is not a coefficient or a problem parameter.  You can only use dot notation to access the coefficients and problem parameters of a cfit or sfit, e.g.,
'f.p1'.

For the current fit, you can access these properties: p1, p2

You can get coefficient names and values either by name, e.g., p1 = f.p1, or by using the coeffnames or coeffvalues functions, e.g., names = coeffnames(f).

To use methods, use functional notation instead, e.g., plot(f). 

>> coeffvalues(f)
ans =
    2.0000   -0.0000

最重要的是:

要使用方法,请改用函数符号,例如 plot(f)。

现在假设我们是虐待狂,并且想要编写一个我们自己行为类似的函数,进一步调查我们发现cfit.coeffvalues 只是私有财产的吸气剂。现在,如果您仔细查看上面的错误,您会注意到它甚至没有出现在cfit.coeffvalues,而是出现在cfit.subsref

总之,

从中我们可以了解到,经验,函数符号直接传递给相关方法,而 OOP 符号首先传递给类的可能被覆盖的 subsref 方法。我想如果您想确保跳过任何自定义 subsref,请使用函数式表示法。

【讨论】:

  • “这不仅仅是语法糖”我不同意。如果您没有定义subsref,则默认情况下obj.method(param) 调用method(obj,param)。这就是语法糖的定义。您可以覆盖默认 subsref 并删除语法糖这一事实并不意味着它不是语法糖。
  • @CrisLuengo 我是这么说的,看到你打败了我:p 另外,如果检查 cfit 类,你会发现 coeffvalues 方法没有在 classdef 中定义,而只是使用首先不支持点访问语法的旧样式。
  • 出色的例子,也是我怀疑的一种原因。谢谢。
  • @HennadiiMadan 不客气;很高兴它有帮助! (也在这个过程中学到了一些东西:))
猜你喜欢
  • 1970-01-01
  • 2022-01-06
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
  • 2021-07-15
  • 2012-08-28
  • 2021-03-28
  • 1970-01-01
相关资源
最近更新 更多