如何在Dart中执行从超类到子类的回调

问题描述 投票:1回答:1

我有一个抽象类,该类将字符串添加到列表中并执行其他一些操作。

abstract class Abc {
  final _list = <String>[];
  Function(String) addedValue;

  void add(String s) {
    _list.add(s);
    if (this.addedValue != null) this.addedValue(s);
  }
}

在我的子类中,每次将字符串添加到列表中时,我都需要一个回调。还有其他子类可能需要也可能不需要回调。

class Xyz extends Abc {
  String _data = '';

  Xyz() {
    this.addedValue = _added;
  }

  void _added(String s) {
    _data += '$s,';
    print('data: $_data');
  }
}
main() {
  var a = Xyz();
  a.add('hello');
  a.add('goodbye');

  a.addedValue('a'); // Prefer if this was not possible.
  a.addedValue = null; // Prefer if this was not possible.
}

为超类提供回调方法的最干净的方法是什么?

  • 我无法在构造函数中传递它,因为它是一个实例方法。
  • 我无法使其变为静态,因为它需要访问该实例。
  • 我不想在子类之外不公开回调方法/设置器。
  • 超类和子类将不在同一个库中。
dart callback subclass superclass
1个回答
0
投票

您可以在setCallback抽象类中创建类似于Abc的方法,该方法可以设置回调,但不再允许调用它。这将使我们能够在构造函数中为Xyz

设置回调。
abstract class Abc {
  final _list = <String>[];
  Function(String) _addedValue;

  void add(String s) {
    _list.add(s);
    if (this._addedValue != null) this._addedValue(s);
  }

  void setCallback(Function(String) callback) => _addedValue = callback;
}

class Xyz extends Abc {
  String _data = '';

  Xyz() {
    setCallback(_added);
  }

  void _added(String s) {
    _data += '$s,';
    print('data: $_data');
  }
}

main() {
  var a = Xyz();
  a.add('hello');
  a.add('goodbye');

  a.addedValue('a'); // No longer possible
  a.addedValue = null; // No longer possible
}

我也确实提出了以下解决方案,但是它是如此丑陋和完全愚蠢,以至于我需要提出另一个更明智的解决方案才能首先展示……但是如果我也想使其他人感到困惑,我会说这是“有效的”。

以下实现的概念是,您不是将变量保存到回调中,而是将变量保存到可以提供回调方法的方法中。

abstract class Abc {
  final _list = <String>[];
  Function(String) Function(Abc) _getCallback;

  Abc(this._getCallback);

  void add(String s) {
    _list.add(s);
    if (this._getCallback != null && this._getCallback(this) != null)
      this._getCallback(this)(s);
  }
}

class Xyz extends Abc {
  String _data = '';

  Xyz() : super((obj) => obj is Xyz ? obj._added : null);

  void _added(String s) {
    _data += '$s,';
    print('data: $_data');
  }
}

main() {
  var a = Xyz();
  a.add('hello');
  a.add('goodbye');

  a.addedValue('a'); // No longer possible
  a.addedValue = null; // No longer possible
}
© www.soinside.com 2019 - 2024. All rights reserved.