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

Защищено в интерфейсах

Почему все методы в определении interface неявно public? Почему это не позволяет использовать метод protected?

4b9b3361

Ответ 1

Потому что интерфейс должен означать "то, что вы можете видеть извне класса". Было бы бессмысленно добавлять непубличные методы.

Ответ 2

Хотя часто приводимая причина заключается в том, что "интерфейсы определяют публичные API", я думаю, что это чрезмерное упрощение. (И он "пахнет" круговой логикой тоже.)

  • Вложенный интерфейс может быть защищен или закрыт, и если это так, он вообще не определяет публичный интерфейс.

  • Было бы бессмысленно иметь интерфейсы, которые имеют смесь модификаторов доступа; например частично публично и частично ограничено другими классами в том же пакете, что и интерфейс. Фактически, в некоторых случаях это может быть непринужденным, ИМО.

На самом деле, я думаю, что часть рассуждений о том, что члены группы неявно публично, заключается в том, что она упрощает Java:

  • Неявно члены публичного интерфейса проще для программистов. Сколько раз вы видели код (классы), где модификаторы доступа к методу были выбраны, по-видимому, случайным образом? Многим "обычным" программистам трудно понять, как лучше всего управлять границами абстракции Java 1. Добавление public/protected/package к интерфейсам делает их еще более трудными для них.

  • Неявно публичные элементы интерфейса упрощают спецификацию языка... и, следовательно, задачу для разработчиков компилятора Java и людей, которые реализуют API Reflection.

Эта линия мышления делает "интерфейсы определения публичных API" следствием (или характеристикой) дизайна языка... не наоборот. На самом деле две линии мысли, вероятно, развивались параллельно в умах дизайнеров Java.


1 - Конечно, программисты с верхним оружием не испытывают никаких трудностей с этими вещами и могут приветствовать более богатую палитру функций контроля доступа. Но что происходит, когда их код передается кому-то другому?

Ответ 3

Я должен сказать, что этот вопрос был вновь открыт введением методов по умолчанию в Java 8. Проект, над которым я сейчас работаю, похож на базовый характер интерфейса, предназначенный для абстрактного намерения от реализация.

Есть несколько случаев, когда я мог бы существенно упростить мой код с помощью метода, защищенного по умолчанию. Оказывается, что это фактически не работает, поскольку интерфейсы по-прежнему придерживаются логики Java 7. Нормальный защищенный метод не имеет особого смысла по указанным выше причинам; но если общедоступный метод по умолчанию требует низкоуровневого ресурса, который вряд ли изменится и может быть предоставлен защищенным методом, мне кажется, что работа с защитой по умолчанию будет не только поддерживать более чистый код, но и защитит будущих пользователей от случайные злоупотребления.

(Это трагически не меняет того факта, что мне все еще нужно слишком усложнять мой код ненужными рефератами, но я намерен разместить запрос функции в Oracle.)

Ответ 4

Поскольку интерфейсы определяют общедоступные API. Все, что защищено, является внутренней деталью, которая не принадлежит интерфейсу.

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

Ответ 5

Возможно, потому что это интерфейс, то есть он должен сообщать клиентам, что они могут делать с экземплярами, а не рассказывать им, что они не могут сделать.

Ответ 6

Интерфейс предназначен для использования в качестве "контракта" для внешнего мира. Если вы хотите использовать защищенные методы, вам, вероятно, лучше использовать абстрактный класс (если это доступно в Java, конечно). Wiki

Кроме того, у этого сообщения, вероятно, есть и отличные ответы: Почему я не могу защитить интерфейсные элементы?

Ответ 7

Я сильно чувствую, что интерфейсы должны обеспечивать защищенные методы; кто сказал, что интерфейсы должны быть видны всем во всем мире? Что касается вашей точки зрения, что это может смутить "обычных" (читай: некомпетентных) программистов: так много ООП - это правильное структурирование объектов, классов, пакетов и т.д., Если программисту нелегко делать все это правильно, у него есть гораздо большая проблема. Java была создана для такого типа вещей.

Ответ 8

Поскольку класс реализации должен реализовывать ВСЕ методы, объявленные в вашем интерфейсе, что произойдет, если ваш класс реализации находится в другом пакете?

Ответ 9

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

Выдержка из Стиль кода об переменных интерфейса, но при этом применяется к методам:

 Интерфейсные переменные неявно публичны, поскольку интерфейсы предназначены для обеспечения интерфейса прикладного программирования (API), который полностью доступен для программистов Java для ссылки и реализации в своих приложениях. Так как интерфейс может использоваться в пакетах Java, отличных от их собственных, видимость общественности гарантирует, что программный код может получить доступ к переменной.

Ответ 10

Защищенные методы всегда доступны подклассу, только если подкласс расширяет базовый класс.

В случае интерфейса подкласс никогда не расширяет интерфейс. Он реализует интерфейс.

Защищенные методы доступны с помощью extend, а не с реализацией.

Ответ 11

Единственный сценарий, когда это имеет смысл, - это когда вы хотите ограничить видимость для одного и того же пакета. Все другие применения protected неприменимы. В частности, методы protected часто используются для обеспечения доступа к некоторым деталям реализаций более низкого уровня для потомков. Но заявляя, что в интерфейсе не имеет смысла, так как не существует более низкой реализации уровня.

И даже пакетный сценарий на самом деле не является интерфейсом.

Чтобы достичь того, чего вы, вероятно, захотите, вам нужны два интерфейса: один для внутреннего использования и один, который вы публикуете в публичном API. (С внутренним, возможно, но не обязательно расширением публичного.) Или, как указывали другие, абстрактный суперкласс.

Ответ 12

Объявление внутренних подинтерфейсов является хорошим практическим, но вы не можете объявить свои внутренние методы как protected в интерфейсе Java, технически.

Конечно, вы можете создать еще один интерфейс для внутреннего использования, который расширяет общий интерфейс:

public interface YourPublicInterface {

    public void doThing1();

    public void doThing2();

    public void doThing3();

    interface Internal extends YourPublicInterface {

        void doAnyInternalThing1();

        void doAnyInternalThing2();

    }

}

Вы можете использовать интерфейс Internal внутри пакета, но вы должны принять любой подтип YourPublicInterface (в общедоступных методах):

public class AClassInYourPackage {

    public void someMethod(YourPublicInterface param) {
        if (param instanceof YourPublicInterface.Internal) {
            // run the optimized code
        } else {
            // run the general code
        }
    }

}

Вне пакета пользователи могут без проблем использовать YourPublicInterface.

В общей практике программисты создают абстрактные классы в подобных ситуациях. Однако в этом случае мы теряем преимущества множественного наследования.

Ответ 13

Хороший вопрос, если спросить, почему разработчики сделали атрибуты интерфейса публичными незащищенными,...?

Разрешение защищенного нарушило бы политику/свойство интерфейса: "любая предоставляемая вами абстракция должна быть доступна везде без каких-либо условий, но не должна позволять ее изменять (например, значение экземпляра var)"

Для такого случая использования вам следует избегать использования интерфейса.

Ответ 14

Интерфейсы предназначены для демонстрации методов во внешнем мире. Таким образом, эти методы являются публичными по своей природе. Однако, если вы хотите ввести абстракцию в пределах одного и того же семейства классов, это можно сделать, создав другой уровень абстракции между вашим интерфейсом и классом реализации, то есть абстрактный класс. Пример демонстрируется ниже.

public interface MyInterface {
    public void publicMethod(); // needs to be public
}

public abstract class MyAbstractClass implements MyInterface {
    @Override
    public void publicMethod() {
        protectedMethod(); // you can call protected method here
        // do other stuff
    }
    protected abstract void protectedMethod(); // can be protected
}

public class MyClass extends MyAbstractClass {
    @Override
    protected void protectedMethod() {
        // implement protected method here, without exposing it as public
    }
}

Ответ 15

Члены интерфейса всегда изменяются/реализуются вне себя (в классе или структуре), поэтому они неявно публичны, и с ним не допускаются модификаторы доступа. Даже члены интерфейса публично реализованы. Однако, если вы хотите сделать член частным в классе, который обеспечивает его реализацию, вам необходимо явно реализовать интерфейс.

interface IMyIF {
int MyMeth(int x);
}
//then it is legal to implement IMyIF as shown here:
class MyClass : IMyIF {
int IMyIF.MyMeth(int x) {
return x / 3;
}
}

Явная реализация дает вам способ реализовать метод интерфейса, чтобы он не был публичным членом класса, который обеспечивает реализацию.