【问题标题】:How to properly proxy "inherited" static methods?如何正确代理“继承”的静态方法?
【发布时间】:2016-10-17 19:12:18
【问题描述】:

我对 Dart 还很陌生,并且仍在学习它带来的所有细微差别。我目前的任务真正让我感到困扰的一件事是从父类继承(或代理)静态方法。

void main() {
  EnglishCasual.greet();
}

class English {
  static greet() {
    actGreeting();
    sayGreeting();
  }

  static sayGreeting() {
    print('hello');
  }

  static actGreeting() {
    print('<tips hat>');
  }
}

class EnglishCasual extends English {
  static sayGreeting() {
    print("m'lady");
  }

  static actGreeting() {
    print('<tips fedora>');
  }
}

上面给出了错误NoSuchMethodError: method not found: 'greet',根据 Dart 文档,这是预期的行为,因为静态方法不是继承的(这对我来说似乎很奇怪,但没关系。继续……)

然后我尝试了一个简单的父类代理...

DartPad Example

但这会产生另一个错误:Invalid context for 'super' invocation'super' is only available in instance methods。好的...让我们通过名称显式调用父类。

DartPad Example

但是,正如预期的那样,这只是对English.greet() 的任何其他呼叫处理,我们得到的是正式的问候而不是随意的问候。有道理。

于是我转向反思。我在 SO 上找到了一个看起来很有希望的 sn-p 并对其进行了测试:

DartPad Example

这导致了错误The method 'greet' is not defined for the class 'EnglishCasual',这是我应该预料到的,因为noSuchMethod 没有被定义为静态,所以它没有被调用静态方法调用。所以,最后一次……

DartPad Example

我们得到另一个错误The name 'noSuchMethod' is already defined in 'core/object.dart'

在这一点上,我没有想法。似乎没有办法完成这个(看似简单的)练习,我真的希望你们能指出我正确的方向。

这样做的正确方法是什么?

【问题讨论】:

  • 静态方法不会被继承,也不能被 AFAIK 代理。
  • 不要使用静态方法

标签: inheritance dart static-methods


【解决方案1】:

正如您所说,静态方法不是继承的。这意味着只有实例方法被继承。 您可以通过一次调用操作调用两个不同函数的唯一方法是:

  • 它正在调用实例方法(包括 getter、setter 和运算符),或者
  • 它正在调用一个函数值。

即:

callA(o) => o.foo(42);  // Instance method.
callB(f) => f(42);  // Function value.

所有其他情况下,要调用的函数是静态确定的,因此您将始终调用完全相同的函数。你不能让你的 greet 函数根据它的调用方式调用不同的函数,除非它本身是一个实例方法或者它需要一个帮助它选择的参数。

换句话说,不要试图用静态函数做聪明的事情。 您正在尝试拥有sayGreetingactGreetingCasualEnglish 版本覆盖 English 中的版本。只有当它们是实例成员时才有效。

【讨论】:

  • 我认为我正在寻找的是所谓的“后期静态绑定”,至少在 PHP 中是这样的。基本上,首先确定所有类层次结构和继承,并在解决/应用覆盖后,然后应用static。 Dart 似乎是static-ing 事情早了。
  • 后期静态绑定只有在静态被继承时才有意义,而在 Dart 中则不然。静态成员与顶级成员没有什么不同,它们只是将类用作命名空间。由于无论如何它们都是静态解析的,因此可以从两个不同的类中使用相同的函数并不被视为优势,您始终可以直接访问正确的函数。
【解决方案2】:

静态方法在 Dart 中不被继承,不能被覆盖等。

打开standard 并搜索10.7 静态方法

【讨论】:

  • 是的,我在最初的问题中也说过这一点。我正在寻找另一种方式来实现我的目标。
【解决方案3】:

只需删除“静态”关键字 - 继承和覆盖将开始工作,如 dartpad 所示。

我建议退后一步看看面向对象编程(OOP)的概念,幸运的是你可以使用Java OOP basics,因为在这种情况下 Dart 是类似的,基于类的面向对象语言。您还可以查看飞镖大师 Seth Ladd 和更普遍的 Wikipedia 所说的内容。

【讨论】:

    猜你喜欢
    • 2023-04-09
    • 2017-02-07
    • 2012-06-21
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 2020-11-13
    相关资源
    最近更新 更多