2

これがここで何十回も質問され、答えられたことは間違いありませんが、満足のいく答えを見つけることができません。

私には、このような静的メソッドを介して抽象親クラスによってのみインスタンス化したいクラスのファミリーがあります(コンパイルを試みずに入力しているここにタイプミスがある可能性があります)。

public abstract class Papa {
    public static Papa newInstance() {
        String strClass = Papa.figureOutTheNameOfChildClassToInstantiate();
        Papa papa = (Papa) Class.forName(strClass).newInstance();
        return papa;
    }
    public abstract void doSomething();
    ...
}
public class Child extends Papa {
    public void doSomething() { /* Do something */ }
}

それは多かれ少なかれ私が今持っているものです。私がやりたいのは、子がファクトリメソッドPapa.newInstance()によってのみインスタンス化できることを確認することです。子の引数のないコンストラクターをプライベートにすることでこれを実行しようとしましたが、Papaはそれをインスタンス化できません。

だから、私の質問は、子インスタンスがファクトリメソッドPapa.newInstance()によってのみ作成されることをどのように確認できますか?

4

2 に答える 2

3

絶対に、積極的に、これを強制したい場合はPapa、型のパラメーターを受け取る保護されたコンストラクターを指定しますXyzzy。で保護Xyzzyされた内部クラスを作成しPapaます。プライベートコンストラクターを与えます。現在、Papaのインスタンスのみを作成できますXyzzyXyzzyのコンストラクターを呼び出すためのインスタンスが必要Papaであり、のサブクラスはPapaコンストラクターからそのコンストラクターを呼び出す必要があるため、Xyzzyの任意のサブクラスのコンストラクターを呼び出すためのインスタンスが必要ですPapa。したがって、Papaそのサブクラスのコンストラクターのみを呼び出すことができます。何もXyzzyしませんが。

Xyzzyサブクラスはインスタンスをリークする可能性があり、他のコードがサブクラスコンストラクターを呼び出すことができるようになります。ただし、使い捨てにすることで、それを制約することもできますXyzzy。これは、単一の静的ファクトリ呼び出しのコンテキスト内でのみ可能です。

しかし、正直なところ、私は気にしません!

于 2012-06-18T12:30:10.050 に答える
3

いくつかの可能な選択肢:

  1. 子クラスコンストラクターのデフォルトの可視性を使用して、それらを親クラスと同じパッケージに配置します。これには、これらのクラスが、「兄弟」クラスを含む、同じパッケージ内の他のクラスによってインスタンス化される可能性があるという欠点があります。

  2. すべての子クラスを親クラスのネストされたクラスとして設定します。それらをとしてマークするprivate staticと、親クラスにのみ表示されます。残念ながら、これはすべてのクラスのコードが同じファイルにあることも意味します...

于 2012-06-18T12:31:59.957 に答える