13

私は効果的なJavaテキストブックを読んでいました。最初の項目は、パブリック コンストラクターの代わりに静的ファクトリ メソッドを使用することです。私の疑問は、私が指定している場合、Interfaceどのように静的ファクトリメソッドを指定できますInterfaceか? Java は 内の静的メソッドをサポートしていないためinterfaceです。テキスト ブックでは、public static factory メソッドを含むインスタンス化不可能なクラスの作成について指定されています。しかし、これらのメソッドはどのようにして実装クラスのプライベート コンストラクターにアクセスできるのでしょうか?

テキストブックには、を定義している場合Interface Type、インスタンス化できないクラスを作成しTypes、そのクラスに静的ファクトリメソッドを含めると書かれています。しかし、クラスで定義されたメソッドは、どのようTypesにして具体的な実装のプライベート コンストラクターにアクセスできますか?Interface Type

編集: - 以下の文は教科書から引用されています。その意味を説明してください

「インターフェイスは静的メソッドを持つことができないため、慣例により、 Typeという名前のインターフェイスの静的ファクトリ メソッドは、Typesという名前のインスタンス化できないクラス (項目 4) に配置されます」

編集:- Joshua Bloch による効果的な Java から取得: Item1 - 静的ファクトリ メソッド

     public interface Foo{ //interface without plural 's' (question 1)
     public void bar();
 }
 public abstract class Foos(){ // abstract factory with plural 's' (question 1)
    public static Foo createFoo(){
        return new MyFoo();
    }
    private class MyFoo implements Foo{ // a non visible implementation (question 2)
       public void bar(){}
    }
 }

私の質問は、静的メソッドがどのようcreateFoo()にしてプライベートコンストラクターを呼び出すことができるかということですMyFoo

4

5 に答える 5

7

インターフェイスを返すようにファクトリを定義できますが、内部的に具象クラスを作成します。

例えば:

public Interface I { }

private class Impl implements I {
}

I buildI() {
    return new Impl();
}

トリックは、パッケージ プライベート (またはそれらが内部クラス プライベートであっても) コンストラクターを使用して実装を作成し、ファクトリのみがそれらをビルドできるようにすることです。

この方法の利点は、ファクトリが要件に応じて適切な実装を構築できることと、すべてがユーザーには見えないことです。たとえば、ファクトリを使用して を作成する場合、ビルド対象のEnumSetにエントリがいくつあるかに応じて、複数の内部実装があります。64 エントリ未満の long for でビットフィールドを使用する超高速バージョン、より長い列挙型の低速バージョン。EnumEnumSetEnums

ファクトリのインターフェイスを指定するには、次のことを行う必要があります。

public interface Factory {
   I buildI();
}

これで、人々はあなたを呼び出すことsetFactory(new FactoryImpl());ができ、次に呼び出すことができfactory.buildI()、コードは具体的な実装を返します。

これをさらに一歩進めて、ジェネリックを使用できます。

public interface GenericFactory<T> {
    T buildInstance();
}

そして、あなたは次のようにsetFactoryなります:

public void setFactory(GenericFactory<I> factory);

ファクトリを作成するには、次のようにします。

public class FactoryImpl implements GenericFactory<I> {
     @override
     I buildInstance() {
        return new impl();
     }
}

しかし、ジェネリックの要件を変更するだけで、ファクトリを必要とするあらゆるものに同じファクトリ クラスを使用できるようになりました。

プライベート コンストラクターを呼び出すことができる理由は非常に単純です。同じクラスで宣言されているからです。

1 つの Java ファイル内で、プライベート コンストラクターを使用してクラスを作成できます。次に、クラス内で静的メソッドを定義します。これは静的ですが、コンストラクターにアクセスするために必要な特権をまだ持っています。

ファクトリと実装が別々のクラスにある場合、それらは同じパッケージに配置され、メソッドはパッケージを非公開ではなく非公開にします。

于 2013-12-13T10:10:14.697 に答える
5

Java 8 では、最終的にインターフェイスに静的メソッドを含めることができます。

詳細については、TechEmpower ブログのこのアーカイブ コピーを参照してください。

于 2013-12-24T05:11:40.350 に答える
0

インターフェイスでファクトリ メソッドを定義することはできませんが、インターフェイスにコンストラクターを含めることもできません。インターフェイスはインスタンス化できません。ポイントは、インターフェイス自体ではなく、インターフェイスを実装するクラスでコンストラクターの代わりにファクトリ メソッドを使用することです。

于 2013-12-13T10:28:31.077 に答える
0

インターフェイスではなく実装で静的ファクトリメソッドを介してオブジェクトを作成することについて話します

public Interface MyInterface {
    public void myFunction();
}

public class MyClass implements MyInterface {

    // constructor is made private
    private MyClass() {}

    // Use this to create object instead use static factory
    public static MyClass getInstance() {
        return new MyClass();
    }

    public void myFunction(){
      // your implementation
    } 
}

以前の投稿でも、静的ファクトリ メソッドについて説明しています。静的ファクトリ メソッドとは何ですか?

本とは別に、以下のリンクもよく読んでい ます http://www.javacodegeeks.com/2013/01/static-factory-methods-vs-traditional-constructors.html

于 2013-12-13T10:14:38.267 に答える