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

Почему класс не может быть определен как защищенный?

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

Мой вопрос: почему мы не можем определить класс как protected?

Я знаю, что мы не можем, но почему? Должна быть какая-то конкретная причина.

4b9b3361

Ответ 1

Потому что это не имеет смысла.

Защищенный член класса (метод или переменная) аналогичен закрытию пакета (видимость по умолчанию), за исключением того, что к нему также можно получить доступ из подклассов.
Поскольку в Java нет такой концепции, как "подпакет" или "наследование пакетов", объявление класса или пакета-частного было бы одним и тем же.

Вы можете объявлять вложенные и внутренние классы как защищенные или закрытые.

Ответ 2

Как известно, для доступа к уровню пакетов и защиты используется уровень пакета, а также классы, отличные от пакета, но который расширяет этот класс (здесь указывается, что вы можете расширить класс, только если он будет виден!). Скажем так:

  • защищенный класс верхнего уровня будет виден классам в его пакете.
  • теперь делает его видимым вне пакета (подклассы) немного запутанным и сложным. Каким классам должно быть разрешено наследовать наш защищенный класс?
  • Если всем классам разрешен подкласс, он будет похож на спецификатор общего доступа.
  • Если нет, то это похоже на значение по умолчанию.

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

Ответ 3

public class A
{
    protected class B
    {
    }
}

Ответ 4

Определение защищенного поля делает это поле доступным как внутри пакета, так и снаружи пакета только через наследование (только внутри дочернего класса).

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

А поскольку пакет не может быть расширен (может быть импортирован), определение защищенного класса снова сделает его закрытым для пакета, что аналогично определению его по умолчанию, что мы уже можем сделать. Поэтому нет никакого смысла в определении частного класса, это только сделает вещи двусмысленными.

Для получения дополнительной информации прочитайте, Почему внешний класс Java не может быть закрытым или защищенным

Ответ 5

Из 4 модификаторов доступа "общедоступный, закрытый, защищенный и по умолчанию" класс может иметь только общедоступный и по умолчанию модификатор.

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

Но, если у вас есть класс без модификатора/по умолчанию, вы не можете даже импортировать его в другой пакет. Например, у вас есть класс: as DefaultClass.java

package home;
class DefaultClass{
..
}

а другой класс - TestingIt.java в другом пакете.

package office;
import home.

В тот момент, когда вы пытаетесь импортировать home.DefaultClass в вышеуказанный код, вы поймете, что наш DefaultClass нельзя импортировать. Это не видно на упаковке вне дома. Мы не можем импортировать его в этот файл TestingIt.java. Почему нет? потому что default = ограничен собственным пакетом.

И теперь на ваш вопрос "почему не может класс защищать модификатор доступа?" Я думаю, что, вероятно, потому, что он не будет отличаться от класса модификатора default/no. Даже если "защищенный класс" был возможен, вы не сможете импортировать его в другой пакет, как "класс по умолчанию/без модификатора".

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

Ответ 6

Ответ @Nikita Rybak имеет хорошие моменты, но нехватку деталей, я не могу просто получить идею, не думая о себе глубоко, следующее - то, что я думал, и теперь я должен полностью понять причину.

Четыре модификатора доступа, предположим, что 1-й уровень является публичным, а 4-й уровень закрытым (основано на этой таблице в последовательности). Первое, что мы должны знать, это то, почему класс не может быть определен как закрытый на верхнем уровне.

Так что, если "private class foo" (определенный закрытый член, т.е. Сам класс является членом) позволяет, что является внешним (который содержит член)? Объем файла? Нет, внешний файл не имеет смысла, потому что даже несколько классов в одном файле будут скомпилированы в отдельные файлы классов. Итак, внешнее - это упаковка. Но модификатор доступа по умолчанию 3-го уровня уже означает "частный пакет ". Таким образом, модификатор частного доступа 4-го уровня не будет использоваться/разрешен.

Но вложенный закрытый класс разрешен, потому что прямым внешним является класс, а не пакет, например:

class PrivateNestedMain {
    private static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

А что если "защищенный класс foo" разрешит? Защищенной главной характеристикой является подкласс, поэтому внешний (пакет) ДОЛЖЕН (из-за объема, но все же необязательно) обеспечивать стиль подкласса, то есть субпакет, или package A extends package B, но мы ничего такого не знаем. Таким образом, защищенный не может использовать полный потенциал (основная область охвата подкласса) на верхнем уровне, который внешним является пакетом (т.е. Такой подпакет не существует), но защищенный может использовать полный потенциал во вложенном классе, который внешним является класс ( т.е. может быть подклассом):

class ProtectedNestedMain {
    protected static class Inner {
        public static void main(String[] args) {
            System.out.println("Hello from Inner!");
        }
    }
}

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

Моя путаница в основном вызвана известной таблицей по адресу https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:

enter image description here

Если 1-й уровень (общедоступный) и 3-й уровень (частный пакет) разрешен, то как, на самом деле, промежуточный уровень 2-й (защищенный) не разрешен?

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

публичный вспомогательный подкласс, если у внешнего есть свойство подкласса.

То же самое вводящее в заблуждение применение к частному пакету, частному пакету не поддерживает подкласс (N в ячейке) не означает, что понятие подкласса применяется во внешнем.

Это означает, что мы должны игнорировать столбец Subclass, если функция подкласса не доступна во external:

enter image description here

Как мы видим сейчас, и защищенный, и закрытый пакет находятся на одном и том же уровне (YYN), больше нет путаницы в том, почему промежуточный уровень не разрешен. В целом, Java выбирает только закрытый пакет, а не защищенный, чтобы избежать путаницы (это просто вопрос выбора, но основной характеристикой защищенного объекта является подкласс, поэтому приватность пакета выше), и в результате на верхнем уровне допускаются только 2 модификатора доступа:

На верхнем уровне - public или package-private (без явного модификатора).

Ответ 7

Защищенный не похож на общедоступный. Защищенный имеет доступ на уровне пакета плюс доступ к ним за пределами пакетов только по наследованию. Если класс говорит A за пределами пакета INHERITS класс из другого пакета (с защищенным методом с использованием INHERITANCE), он может получить доступ к методам этого класса B, которые имеет защищенные методы, но подклассы, полученные из этого класса, т.е. A не могут получить доступ к защищенным методам.. противоположное происходит с публичным.

Пример:

package 2;
class B
{
protected void method1()
{
}
}
package 1;
import 2.B;
class A extends B
{
//can access protected method
}
class C extends A
{
//can't access the protected method
}

Ответ 8

поведение "protected" = поведение "default" + "использовать его в любом подклассе в любом пакете".

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

Ответ 9

Защищено: ВИДИМ только для уровня пакета *.

класс определен как защищенный ---> он не может быть расширен из внешнего пакета (не виден).

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

То же самое относится к частным определенным классам.

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

*: Изучите защищенное ключевое слово, для этого ответа я сделал его кратким.

Ответ 10

Ответ от @Akash5288 не имел для меня никакого смысла:

Если всем классам разрешено создавать подклассы, то это будет похоже на спецификатор открытого доступа.

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

Затем вы можете применить ту же логику к защищенным методам и переменным, они также "похожи на публичные". Все классы вне пакета могут расширять наш открытый класс и использовать его защищенные методы. Почему ограничение методов и переменных расширенными классами нормально, а всего класса - нет? "Подобно публике" - это не то же самое, что и публике. Моя интерпретация заключается в том, что разрешить защищенный класс совершенно нормально, так же как и защищенные методы.

Ответ "Вы не можете расширить класс, к которому вы не можете получить доступ/увидеть" более логичен.

Ответ 11

Что имеет смысл в этом вопросе, так это то, что JVM написана на C (Sun JVM) и C++ (oracle JVM), поэтому во время компиляции мы собираемся создавать файлы.class из нашего java файла, и если мы объявим класс с Защищенное ключевое слово, тогда оно не будет доступно JVM.

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

Точно так же класс высшего уровня не может быть закрытым. Объяснение как ниже:

Так что же произойдет, если мы определим класс private, этот класс будет доступен только внутри сущности, в которой он определен, а в нашем случае это его пакет?

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

Ответ 12

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

Пример:

package a;
class parent{
 protected void p();
}
package b;
import a.p;
class child extends parent{
  //you can access method which is protected in the parent in the child 
}
class another extends child {
 //here you can not access the protected method 
}