3

オブジェクトのインスタンス化を制御したい場合、コンストラクターをプライベートまたは内部にすることがよくあります。

public class A {
    private A(int aParam) { }
}

ただし、これは基本的にクラス「A」を封印することと同じです。これは、誰も継承できないためです。

したがって、コンストラクターを保護することができます。

public class A {
    protected A(int aParam) { }
}
public class B {
    protected B(int aParam) : base(aParam) { }
}

ただし、これは、B (または B から派生した任意のクラス) のコードが新しい A をインスタンス化できることを意味します。

インスタンス化を制御する方法を探していますが、クラスをシールする必要はありません (効果的またはその他の方法で)。

注: とにかく、リフレクションやその他のトリックを使用してクラスをいつでもインスタンス化できることは知っています。私は明示的な「契約」を作成することにのみ興味があります。誰かが私の契約を故意に覆そうとするなら、それは彼ら次第です。

4

3 に答える 3

7

インスタンス化を制御する方法を探していますが、クラスをシールする必要はありません (効果的またはその他の方法で)。

これはあなたの要件とは本当に矛盾しています。

サブクラスの作成を許可する場合、サブクラスが効果的に親を作成できるようにする必要があります。つまり、少なくとも 1 つのprotectedコンストラクターが必要です。これがないと、サブクラスがインスタンスを適切に初期化する方法がありません。

コンストラクターを保護されたものとして公開することにより、サブクラスがインスタンス化規則を変更できるようになります (常にパブリック コンストラクターを追加できます)。

ここには、実際には 2 つのオプションしかありません。

  1. コンストラクターを保護し、サブクラスが「正しいこと」を行うと仮定します(シナリオに関係なく)、または
  2. クラスを封印し、選択した構築方法を公開します。これにより、サブクラスが防止されますが、継承ではなく構成を介してクラスが再利用されることは防止されません。
于 2013-08-13T17:28:32.477 に答える
0

サブクラスをインスタンス化できるようにしたいが、基本クラスの明示的なインスタンス化を禁止したい場合は、次の 2 つのオプションがあります。

  • 純粋仮想メソッドを追加して、基本クラスを抽象化します。

  • 保護されたコンストラクターを追加し、"new" 演算子をオーバーロードして、抽象ではない場合でも基本クラスの明示的なインスタンス化を禁止します。

于 2013-08-13T18:07:17.013 に答える