Защищено в интерфейсах - PullRequest
98 голосов
/ 21 марта 2011

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

Ответы [ 15 ]

1 голос
/ 28 марта 2016

Объявление внутренних подынтерфейсов - хорошая практика, но технически вы не можете объявить свои внутренние методы как 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.

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

1 голос
/ 21 марта 2011

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

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

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

0 голосов
/ 13 июня 2019

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

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
    }
}
0 голосов
/ 10 августа 2018

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

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

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

0 голосов
/ 21 марта 2011

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

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;
}
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...