首页 > 解决方案 > (Dart)私有和非私有类构造函数中私有和非私有初始化器的作用?

问题描述

我是 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;
...
}

标签: oopdartconstructor

解决方案


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

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

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

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


推荐阅读