Dart - 从父类方法访问继承的静态属性的方法

Posted

技术标签:

【中文标题】Dart - 从父类方法访问继承的静态属性的方法【英文标题】:Dart - Way to access a inherited static property from a parent class method 【发布时间】:2022-01-24 00:29:23 【问题描述】:

php 中,有一种方法可以访问在继承者上定义/覆盖的静态属性值。

例如

class Foo 
   public static $name='Foo';
   public function who()
     echo static::$name;//the static operator
   

class Bar extends Foo 
   public static $name='Bar';

$bar = new Bar();
$bar->who();
//Prints "Bar";

有没有办法用 Dart 语言做完全相同的事情?

【问题讨论】:

静态方法和变量只是定义它们的类的一部分。在扩展(或实现)时,您不会将它们放入子类中,因为它们不是类接口的一部分。 这是 PHP 的一个很好的特性。为设计开辟了巨大的可能性。我必须想出另一种方法来完成我想要的设计。 this 可能有帮助 我读过那个话题。这些建议确实满足了他的需要。不过我的有点不同。 如果你想让一个方法被派生类覆盖,让它成为一个非static的方法。覆盖static 方法通常没有意义,因为覆盖必然需要一个对象实例才能发生虚拟调度。 static 方法中“静态”的含义是它在编译时是可解析的。允许这种覆盖工作的语言只是因为它们允许调用类方法作为实例方法;如果这是您想要的,只需首先将其设为实例方法即可。 【参考方案1】:

寻址 cmets:

关于使其成为实例道具/方法:静态属性和方法的存在是有原因的,它不必创建对象的新实例来访问不可变的值或功能。

是的,但这不是使用它的方式。 您的用例是调用对象的方法,因此您确实需要一个实例方法。现在,一些语言自动允许调用类方法作为实例方法,我看到提供这种能力的语言有两种选择:

根据对象的已声明类型(不是运行时类型)将fooInstance.classMethod() 静态转换为ClassFoo.classMethod()。这就是 Java 和 C++ 所做的。

隐式生成调用类方法的虚拟实例方法。这将允许fooInstance.classMethod() 基于对象的运行时类型调用适当的方法。例如,给定:

class Foo 
  static void f() => print('Foo.f');

你可以写:

class Foo 
  static void classMethod() => print('Foo.f');
  final instanceMethod = classMethod;

然后您可以致电 Foo.classMethod()Foo().instanceMethod() 并执行相同的操作。

在任何一种情况下,它都是语法糖,因此不是你自己做不到的事情。

关于“静态的含义”和“仅因为它们允许将类方法作为实例方法调用而起作用”:这种肯定实际上是错误的。在 PHP 的情况下,根据上面的示例,语言提供了一种访问调用继承链中方法的类的 TYPE 的方法。 A(methodA) >B > C。当C调用methodA时,PHP让你知道你所在的类类型确实是C,但没有附加对象实例。 “静态”这个词是调用者类类型本身的替代品

所有这些在编译时仍然是已知的。 C派生自B派生自A是静态已知的,因此当您尝试调用C.methodA时,编译器知道它需要在B中查找methodA,然后在A中查找.运行时不会发生动态调度;那仍然是编译时语法糖。也就是说,如果你愿意,你可以明确地写:

class A 
  static void methodA() 


class B extends A 
  static void methodA() => A.methodA();


class C extends B 
  static void methodA() => B.methodA();


无论如何,在你的例子中,你可以这样写:

class Foo 
   static String name = 'Foo';
   String get nameFromInstance => name;
   
   void who() 
     print(nameFromInstance);
   

class Bar extends Foo 
   static String name = 'Bar';
  
   @override
   String get nameFromInstance => name;


void main() 
  var bar = Bar();
  bar.who(); // Prints: Bar

【讨论】:

我明白这一点,当然。但我已经知道的一切。问题是,我可能不得不将我打算做的所有事情都放在最初的问题上,以显示实际问题和实际设计,以便我们弄清楚。实际上,我正在尝试创建一个模型类,例如 Ruby on Rails ActiveRecord。有史以来最好的模型数据库设计之一。但似乎flutter不希望它运行。即使使用 json 可序列化,我也必须对其进行分叉以使其实际创建更有意义的方法。 你觉得值得解释一下 Ruby ActiveRecord 是如何工作的,这样我们就可以弄清楚一些事情吗?我从 1.x 开始就一直在使用颤振,现在它已经 100% 好了,特别是在 2.8 之后。但是,作为 Firestore 数据库的模型类,可以轻松配置和准备这些东西,因此当您执行 someProductInstance.save() 之类的操作时,一切都发生在该调用的背景上,包括断言和所有,但所有功能都继承了来自父模型/ActiveRecord。 我可以说的一件事是,如果 json_serializable 有一个实例方法来从 JSON 而不是工厂填充对象,我可以使用它并继续前进而无需静态的东西。但是如何动态调用继承的类工厂构造函数?嗯,不能。也许我会分叉 json_serializable 并这样做。或者你和其他谷歌工程师可以帮我解决这个 ActiveRecord 类 我 100% 相信,这个类设计遵循 ruby​​ 的大部分 ActiveRecord 内容,将改变 Firestore 和 Flutter 结合的游戏规则。 @GuilhermeFerreira 一个清楚的例子来说明你想要完成的事情会有很大帮助。就目前而言,它似乎是一个XY problem,你认为你可以用继承的静态属性来解决它(同样,这只是语法糖,因此不会让你做任何你已经不能做的事情)。

以上是关于Dart - 从父类方法访问继承的静态属性的方法的主要内容,如果未能解决你的问题,请参考以下文章

简述在类的继承关系中,子类可以继承父类的都有哪些成员

子类从父类继承过来的方法可以操作子类自己定义的成员变量吗

Typescript中的类

pytho类继承与访问控制

java中私有的属性、静态成员可以被子类继承吗?

Java复习类的重用