Почему у вас не может быть защищенного абстрактного класса в Java? - PullRequest
7 голосов
/ 17 ноября 2011

У меня есть абстрактный класс, который выглядит так:

abstract class AbstractFoo implements Bar {
  //Code goes here
}

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

protected abstract class AbstractFoo implements Bar {
  //Code goes here
}

Почему у вас не может быть защищенного абстрактного класса в Java?

РЕДАКТИРОВАТЬ: я, вероятно, должен упомянуть, что это не ванильная Java, а фактически Blackberry / J2ME.

Ответы [ 6 ]

24 голосов
/ 17 ноября 2011

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

Для класса, в котором вы используете ключевое слово ...

  • private: Виден только этому классу

  • (по умолчанию / пакет private): Виден только этому классу и классам в его пакете

  • защищено: Доступно для этого класса, классов в его пакете и подклассов этого класса

  • public: Доступно для любого класса

Классы верхнего уровня не могут быть объявлены private , потому что тогда ничто никогда не сможет получить к ним доступ.

Но вашВопрос заключается в том, почему они не могут быть объявлены защищенными .Ясно, что защищенный класс верхнего уровня (если бы он мог существовать) был бы видим для себя (каждый класс виден для себя).Также ясно, что защищенный класс верхнего уровня будет виден классам в его пакете.Однако сделать его видимым для его подклассов довольно сложно.Каким классам должно быть разрешено наследовать наш защищенный класс?

Если это все они, тогда наш класс может быть также public , потому что тогда мы говорим, что любой класс имеетправо доступа к нашему защищенному классу.Если это не один из них, то наш класс также может быть package-private , поскольку выполняются только два других условия (видимых для себя и вещей в его пакете).И это не может быть «некоторые из них», так как нам нужен способ определить, какие классы могут получить к нему доступ, для чего вообще нужен модификатор видимости.

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

6 голосов
/ 17 ноября 2011

Классы верхнего уровня могут быть только общедоступными или приватными (по умолчанию).

public class PublicClass { 

    protected class InnerClass { } //protected makes sense here

}

class PackagePrivateClass { }

Поскольку: PublicClass и PackagePrivateClass оба являются классами верхнего уровня, они не могут иметь другие модификаторы доступа, private и protected.

Для классов верхнего уровня допускаются только общедоступные и модификаторы доступа по умолчанию.Но для внутренних классов-членов также допускаются другие модификаторы.

Этот реферат здесь, скорее всего, не имеет ничего общего.

4 голосов
/ 17 ноября 2011

можно;следующий код прекрасно компилируется :

public class Main {

    interface Bar {}

    protected abstract class AbstractFoo implements Bar {}

    public static void main(String[] args) {}
}
0 голосов
/ 17 ноября 2011

Классы верхнего уровня не могут иметь область действия protected, только public или package.Вот хорошая ссылка , объясняющая допустимое использование модификаторов области видимости в классах.

0 голосов
/ 17 ноября 2011

IMO, это похоже на недопустимый модификатор, потому что защищенный означает, что он должен быть виден в пакете + в производных классах.Но для того, чтобы объявить, что какой-то класс расширяет этот защищенный класс, вам сначала нужно увидеть его оттуда, чего не может быть, потому что он виден только из производных классов (учитывая, что суперкласс и подклассы не совпадают)пакет).

Если вы хотите видеть класс только из других классов в том же пакете, то будет работать модификатор по умолчанию (package-private), нет причины для работы защищенного модификатора - он только добавляетсовершенно нелогичная и бесполезная способность видеть класс из его производных классов, что

a) не может произойти, если этот класс и его производные классы не находятся в одном пакете.

b) может произойти, учитывая, что этот класс и его производные классы находятся в одном пакете - в любом случае это будет работать с модификатором по умолчанию (package-private).

0 голосов
/ 17 ноября 2011

Я не верю предпосылке вопроса. Я успешно скомпилировал следующий код:

class prot
{
    public abstract class pubab
    {
    }

    protected abstract class protab
    {
    }

    abstract class packprivab
    {
    }

    private abstract class privab
    {
    }
}

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

Вы пытались иметь защищенный класс верхнего уровня (не разрешен)?

...