【问题标题】:Role of private & non-private initializers in (Dart) private & non-private class constructors?(Dart)私有和非私有类构造函数中私有和非私有初始化器的作用?
【发布时间】:2021-07-20 21:07:21
【问题描述】:

我是 OOP 的新手,目前理解水平中等。我通过学习 Dart 和 C# 不断取得进展。我也在探索设计模式,以真正了解它们如何根据不同的场景一起点击。至于现在,我试图理解以下与类构造函数相关的 4 个场景。我了解下划线在构造函数级别和初始化程序级别的含义。但我正在寻找一些对于经验丰富的程序员来说似乎非常明显和清晰的东西。请分享您的宝贵见解,因为我不知道我在这里缺少什么。

场景 1:没有初始化器的私有构造函数

我知道这与 Singleton 不同。 Singleton 允许单个实例化,下面的这个甚至一次都没有。还有其他的吗?

现实世界的例子:

class Firebase {
  // Ensures end-users cannot initialize the class.
  Firebase._();
...
}

场景 2:具有可选公共或非私有初始化程序的私有构造函数

这种具有非私有初始化器(this.app)的私有构造函数有什么用?为什么在私有构造函数中有一个非私有初始化器(this.app)?这样做有什么收获?

现实世界的例子:

class FirebaseAuth extends FirebasePluginPlatform {
/// The [FirebaseApp] for this current Auth instance.
  FirebaseApp app;

  FirebaseAuth._({required this.app})
      : super(app.name, 'plugins.flutter.io/firebase_auth');

  /// Returns an instance using the default [FirebaseApp].
  static FirebaseAuth get instance {
    FirebaseApp defaultAppInstance = Firebase.app();

    return FirebaseAuth.instanceFor(app: defaultAppInstance);
  }
...
}

场景 3:带有私有初始化器的公共构造函数

为什么在非私有构造函数中有私有属性?这样做有什么收获?

虚构的例子:

class Constructify {
  Map<String,dynamic> _property;
  Constructify(this._property);
...
}

场景 4:带有私有初始化器的私有构造函数

当构造函数本身是私有的时,为什么还要有一个私有初始化器?这样做有什么收获?

现实世界的例子:

class FirebaseApp {
  /// A [FirebaseApp] instance can only be accessed from a call to `app()` [FirebaseCore].
  ///
  /// This constructor ensures that the delegate instance it is constructed with is one which extends [FirebaseAppPlatform].
  FirebaseApp._(this._delegate) {
    FirebaseAppPlatform.verifyExtends(_delegate);
  }

  final FirebaseAppPlatform _delegate;
...
}

【问题讨论】:

  • 嗨 Asif,欢迎来到 Stack Overflow。就目前而言,您的问题有点太宽泛了;请一次专注于一个问题或问题。在这里,您要问 ~6 个不同的问题。

标签: oop dart constructor


【解决方案1】:

场景 1:Dart 中的_ 表示变量/方法/函数/构造函数是包私有的。因此,只要我们在同一个包内,就可以使用该字段。因此,在场景 1 中,这实际上意味着如果我们从声明了 Firebase 的包中调用构造函数,我们只能创建 Firebase 对象。这也将阻止您在另一个包中扩展该类,因为我们无法在我们扩展的 Firebase 类上调用构造函数。

场景 2:包私有构造函数确保对象只能由同一包中的代码创建。命名的app 参数标记为required,因此它不是可选的。创建对象后,您可以在这种情况下更改app 变量。我不知道这在这种情况下是否有意义,但你可以做到。在大多数情况下,我会正确地将app 标记为final

场景 3:可以使用构造函数将私有字段设置为一个值,但由于该字段是包私有的,因此我们可以确保我们包之外的任何人都无法访问该字段。

场景 4:同一个包中的一些其他代码使用包私有构造函数。如果您想确保只允许您自己的包创建 FirebaseApp 的新对象,并且不希望您的包之外的代码访问字段 _delegate,您可以执行此示例的操作。

【讨论】:

  • @AsifShaikh 没问题。如果您没有其他问题,并且认为我的回答确实回答了所有问题,请接受我的回答。
猜你喜欢
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-20
相关资源
最近更新 更多