Подтвердить что ты не робот

Зачем публиковать частный публичный класс на Java?

В чем причина объявления члена частной внутренней публики класса в Java, если к нему по-прежнему нельзя получить доступ за пределами класса? Или может это?

public class DataStructure {
    // ...

    private class InnerEvenIterator {
        // ...

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

Ответ 1

Если класс 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;
    }     

}

Ответ 2

Этот метод можно сделать public, чтобы указать, что он семантически открыт, несмотря на то, что компилятор не применяет правила видимости в этом конкретном случае.

Представьте, что во время некоторого рефакторинга вам нужно сделать этот внутренний класс верхнего уровня. Если этот метод private, как вы решаете, следует ли его сделать public, или использовать более ограничительный модификатор? Объявляющий метод как public сообщает читателю о намерениях оригинального автора - этот метод не следует рассматривать как деталь реализации.

Ответ 3

Это полезно, когда вы реализуете любой 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            
    }
}

Ответ 4

Я думаю, вам не хватает реализации части интерфейса Iterator в вашем примере кода. В этом случае вы не можете заставить метод hasNext() иметь какой-либо другой идентификатор видимости, отличный от общедоступного, так как это приведет к уменьшению его видимости (методы интерфейса имеют общедоступную видимость), и он не будет компилироваться.

Ответ 5

Существует много комбинаций модификаторов доступа, которые не являются полезными. Открытый метод в частном внутреннем классе полезен, если он реализует открытый метод в открытом классе/интерфейсе.

public class DataStructure {
    // ...

    private class InnerEvenIterator implements Iterator {
        // ...

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

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

BTW: абстрактные классы часто имеют конструкторы public, когда на самом деле они protected

Ответ 6

Если внутренний класс является закрытым, он не может быть доступен по имени вне внешнего класса. Внутренний и внешний классы имеют доступ к другим частным методам и частным переменным экземпляра. Пока вы находитесь внутри внутреннего или внешнего класса, модификаторы 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 по-прежнему остается единственным классом, который может получить к нему доступ. Используйте любой модификатор, который вам нравится, он не имеет функциональных различий. Единственный раз, когда вы не можете выбирать наугад, - это когда вы реализуете или расширяете, и в этом случае вы не можете уменьшить доступ, но можете его увеличить. Поэтому, если абстрактный метод имеет защищенный доступ, вы можете изменить его на публичный. На самом деле ни один из них не имеет никакого значения.

Если вы планируете использовать внутренний класс в других классах и, следовательно, публиковать его, вы, вероятно, не должны делать его внутренним классом в первую очередь.

Кроме того, я не вижу никаких требований к внутренним классам, расширяющим или реализующим другие классы. Для них это может быть распространено, но это, безусловно, не требуется.