36

クラスを含む外部でまだアクセスできない場合、Javaでプライベート内部クラスのメンバーをパブリックと宣言する理由は何ですか? それともできますか?

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }
}
4

7 に答える 7

36

クラスがクラスを拡張したり、インターフェイスを実装したりしない場合、InnerEvenIterator他のクラスがそのインスタンスにアクセスできないため、ナンセンスだと思います。

ただし、他の非プライベート クラスまたはインターフェイスを拡張または実装する場合は、意味があります。例:

interface EvenIterator {
    public boolean hasNext();
}


public class DataStructure {
    // ...

    private class InnerEvenIterator implements EvenIterator{
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    InnerEvenIterator iterator;

    public EvenIterator getIterator(){
         return iterator;
    }     

}
于 2011-06-07T11:45:26.537 に答える
17

publicこの特定のケースではコンパイラーが可視性ルールを強制しないという事実にもかかわらず、このメソッドは、セマンティックにパブリックであることを示すために作成できます。

いくつかのリファクタリング中に、この内部クラスをトップレベルにする必要があると想像してください。この方法がの場合private、どのように作成するかpublic、またはより制限的な修飾子を使用するかを決定しますか?読者に元の作成者の意図を伝えるようにメソッドを宣言するpublic-このメソッドは、実装の詳細と見なされるべきではありません。

于 2011-06-07T11:54:27.740 に答える
11

を実装する場合に便利ですinterface

class DataStructure implements Iterable<DataStructure> {

    @Override
    public Iterator<DataStructure> iterator() {
        return new InnerEvenIterator();
    }
    // ...        

    private class InnerEvenIterator implements Iterator<DataStructure> {
        // ...    
        public boolean hasNext() { // Why public?
            // ...
            return false;
        }

        @Override
        public DataStructure next() {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }

    public static void main(String[] ex) {
        DataStructure ds = new DataStructure();
        Iterator<DataStructure> ids = ds.iterator();
        ids.hasNext(); // accessable            
    }
}
于 2011-06-07T11:48:47.160 に答える
4

Iteratorサンプルコードにインターフェイス部分を実装していないと思います。その場合、メソッドに public 以外の他の可視性識別子を持たせることはできません。これは、その可視性が低下することになり (インターフェイス メソッドには public 可視性がある)、コンパイルされないためです。hasNext()

于 2011-06-07T11:49:04.203 に答える
3

役に立たないアクセス修飾子の組み合わせがたくさんあります。プライベート 内部クラスのパブリック メソッドは、パブリック クラス/インターフェイスにパブリック メソッドを実装する場合にのみ役立ちます。

public class DataStructure {
    // ...

    private class InnerEvenIterator implements Iterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }

    public Iterator iterator() {
        return new InnerEvenIterator();
    }
}

ところで:抽象クラスはpublic、実際にはコンストラクターを持っていることがよくありますprotected

于 2011-06-07T11:51:53.743 に答える
2

内部クラスが private の場合、外部クラスの外部から名前でアクセスすることはできません。内部クラスと外部クラスは、互いのプライベート メソッドとプライベート インスタンス変数にアクセスできます。内部または外部クラス内にいる限り、修飾子 public と private は同じ効果があります。あなたのコード例では:

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        public boolean hasNext() { // Why public?
            // ...
        }
    }
}

クラス DataStructure に関する限り、これは次のものと完全に同等です。

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

        private boolean hasNext() {
            // ...
        }
    }
}

これは、DataStructure のみがアクセスできるためであり、パブリックまたはプライベートのどちらに設定しても問題ありません。いずれにせよ、DataStructure は依然としてそれにアクセスできる唯一のクラスです。どちらの修飾子を使用しても、機能的な違いはありません。無作為に選択できないのは、実装または拡張するときだけです。この場合、アクセスを減らすことはできませんが、増やすことはできます。したがって、抽象メソッドがアクセスを保護している場合は、それをパブリックに変更できます。確かに、どちらも実際には違いはありません。

他のクラスで内部クラスを使用することを計画している場合、それをパブリックにする場合は、そもそもそれを内部クラスにするべきではありません。

さらに、他のクラスを拡張または実装する内部クラスの要件は見当たりません。そうするのが一般的かもしれませんが、必須ではありません。

于 2013-01-11T08:24:36.280 に答える