Equatable 的子类将啥传递给超级(Equatable 类)?

Posted

技术标签:

【中文标题】Equatable 的子类将啥传递给超级(Equatable 类)?【英文标题】:what does the child class of Equatable pass to the super(Equatable class)?Equatable 的子类将什么传递给超级(Equatable 类)? 【发布时间】:2020-01-28 00:44:02 【问题描述】:

嗨,我是新来的 bloc,我正在尝试理解块计时器 In the doc of flutter_bloc,我会知道这个构造函数类是什么意思


@immutable
abstract class TimerState extends Equatable 
  final int duration;

//and this list props ??
  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));

【问题讨论】:

能否请您根据您的问题更具体地定义您的问题? 为什么要添加这个:dart [List props = const []] dart super([duration]..addAll(props)); 是什么意思 对于在使用 equatable 版本 > 0.6.x(您应该在 2020 年使用)时看到此问题的任何人,这不再适用并且已被删除,有利于要求重载 prop getter 方法. 【参考方案1】:

更新:Equitable 包>= v 0.6.0 的新版本请阅读我的article on Medium,对于旧版本或深入了解请阅读此答案。


当你父亲给你和你兄弟两件礼物时,两件礼物都是笔记本电脑,但不是同一类型的笔记本电脑;你想知道两个礼物是否相等!因此,您将比较对您而言重要的所有方面RAM、SSD、CPU。

在纸上:myLaptop: 16G/256G/i5 | myBrotherLaptop: 8G/512G/i5

假设你的大脑正在使用 Dart 语言,并且你认为每个礼物都是这个类的对象:

class LaptopGiftClass 
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(this.ram, this.ssd, this.cpu);


然后比较使用上面的类创建的两种礼物的相等性,Dart 和其他面向对象的语言(例如 Java、C#)期望您创建(覆盖)这些函数,以使这些语言理解对象并能够比较同一类的任意两个对象:

@override
bool operator ==(Object myBrotherLaptop) =>
    identical(myLaptop, myBrotherLaptop) ||
    myBrotherLaptop is LaptopGiftClass &&
    runtimeType == myBrotherLaptop.runtimeType &&
    name == myBrotherLaptop.name;

@override
int get hashCode => name.hashCode;

如果这些台词把你吓跑了,没有人会责怪你,这就是为什么好人为我们创建了equatable package!

Equatable package 告诉你“把这个可怕的工作留给我” 但是如何将可怕的代码委托给equatable package??! 通过做两件事:

    让你的类扩展相等: dart class LaptopGiftClass extends Equatable ... 从一开始就将数组中需要比较的所有属性传递给 Equatable(超/父类),因此在构造函数中:
LaptopGiftClass(this.ram, this.ssd, this.cpu) : super([ram, ssd, cpu]);

你的最后一课是:

class LaptopGiftClass extends Equatable 
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(this.ram, this.ssd, this.cpu) : super([ram, ssd, cpu]);



你已经完成了!您现在可以检查两个礼物的相等性,只需创建对象然后比较:

LaptopGiftClass myLaptop = LaptopGiftClass(16,256,'i5');
LaptopGiftClass myBrotherLaptop = LaptopGiftClass(8, 512,'i5');

在开始比较之前,您的兄弟看到了您,因为他是一名游戏玩家,他希望您在此相等性检查中添加更多属性:GPU 和 Screen_Resolution!你妈妈听说了,让你也加价格

现在您有一个新道具列表可供比较:[GPU、Screen_Resolution、Price]。

因此,由于您遵循干净代码原则,因此您期望如此,并且您使构造函数能够获取更多属性以进行比较:

// This only mean combine both lists
[ram, ssd, cpu]..addAll(myBrotherAndMotherProps) 

所以你的最后一课是:

class LaptopGiftClass extends Equatable 
  int ram;
  int ssd;
  String cpu;

 // Default constructor
 LaptopGiftClass(
    this.ram, 
    this.ssd, 
    this.cpu, 
    // List of list => because we think "clean code" 
    // and maybe in the future we will send other data; NOT 
    // only an array(list)..
    // so we here sent the extra props we need to
    // compare 'myBrotherAndMotherProps', and 
    // as sometime brother and mother will not ask you 
    // to add props to compare, you give it a default value 
    // as empty "const []", why const here??! just for better 
    // performance as we are so soooo Professional!!

    [ List myBrotherAndMotherProps = const [] ],

 ) : super([ram, ssd, cpu]..addAll(myBrotherAndMotherProps));

 // WHY TO PASS FROM INSIDE THE CONSTRUCTOR? 
 // because Equatable needs them (required) 
 // and not at anytime but immediately inside the 
 // constructor of itself, so we made this 
 // chaining(constructor pass to another constructor)..


因此,很明显,基本属性是 [RAM、SSD、CPU],但任何额外的东西也会被考虑在内,因为我们使实现变得干净、灵活和可扩展。

在添加这个灵活的代码List<Object> get props => [RAM, SSD, CPU]..addAll(myBrotherAndMotherProps);之前,这些代码曾经是相等的!!:

// Note first 3 are equal [ram, ssd, cpu]:
LaptopGiftClass myLaptop = LaptopGiftClass(16,256,'i5', ['Nvidia', 1080, '1200$']);
LaptopGiftClass myBrotherLaptop = LaptopGiftClass(16, 256,'i5', ['Intel HD', 720, '900$']);

myLaptop == myBrotherLaptop; // True without ..addAll(myBrotherAndMotherProps);
myLaptop == myBrotherLaptop; // False with ..addAll(myBrotherAndMotherProps);

TimerState 发生同样的情况:

@immutable
abstract class TimerState extends Equatable 
  final int duration;

  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));

TimerState 的实现与上面的LaptopGiftClass 一样(最后一个实现)。 您可以使用构造函数将props 发送给它:

TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));

所以TimerState 将在这一行中将 props 的列表传递给它的父级(super/ Equatable/ what extended..),如下所示: : super([duration]..addAll(props));

在这个计时器示例中; duration 是基本的道具,就像 [RAM, SSD, CPU] 到 LaptopGiftClass。

层次结构是这样的:

// Inside class Paused extends TimerState ...
Paused(int duration) : super(duration); // super is TimerState

// then Inside abstract class TimerState extends Equatable ..
TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props)); // super is Equatable

// Then Equatable will get props and deal with it for you...

【讨论】:

很好的解释。 那里有一些扎实的理解!不错的@Jehad Nasser :)【参考方案2】:

本教程使用equatable: ^0.2.0,在此版本中,当您想要覆盖hashcode== 运算符时,您需要将属性的List 传递给super 构造函数。查看docs。

考虑到这一点,他创建了一个名为props 的可选参数,并将包含durationprops 参数的所有元素的List 传递给超级构造函数。

abstract class TimerState extends Equatable 
  final int duration;

  TimerState(this.duration, [List props = const []])
      : super([duration]..addAll(props));

这样扩展TimerState的类可以使用props可选参数来传递其他属性,并且这些属性将被添加到List中,该super构造函数被传递给TimerState正确使用Equatable

因此,如果您需要具有其他属性的状态,则需要这样做:

class OtherTimerState extends TimerState 
  final int otherProperty1;
  final int otherProperty2;

  OtherTimerState(int duration, this.otherProperty1, this.otherProperty2)
      : super(duration, [otherProperty1, otherProperty2]);

【讨论】:

以上是关于Equatable 的子类将啥传递给超级(Equatable 类)?的主要内容,如果未能解决你的问题,请参考以下文章

应该将啥模块实例传递给 CreateCursor 方法?

应该将啥传递给 if() 以打印“Hello World”?

将啥传递给 sqlite create_function 任意指针

将啥传递给 Android 的 NDK 以便可以使用 OpenCV 加载图像?

我应该将啥传递给 SQLitePCL.raw.SetProvider() 以避免“'Microsoft.Data.Sqlite.SqliteConnection' 的类型初始化程序引发异常”

Oracle 将啥 SQL 数据类型分配给“count(*)”?