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


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

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

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

12 54

12 ответов:

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

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

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

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

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

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

public class A
{
    protected class B
    {
    }
}

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

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

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

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

из 4 модификаторов доступа "public, private, protected and default" класс может иметь только модификатор public и default.

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

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

package home;
class DefaultClass{
..
}

и еще один класс В качестве TestingIt.java в другом пакете.

package office;
import home.

в тот момент, когда вы пытаетесь импортировать домой.DefaultClass в приведенном выше коде вы поймете, что наш DefaultClass не может быть импортирован. Это не видно для пакета вне дома. Мы не можем импортировать его в этот TestingIt.Java-файл. Почему бы и нет? потому что по умолчанию ограничена его собственном пакете.

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

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

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

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

Так что если "частный класс foo " (частный член определен, т. е. сам класс является членом) разрешить, что такое внешний (который содержит член)? объем файла ? нет, file outer бессмысленно, потому что даже несколько классов в одном файле будут скомпилированы в отдельные файлы классов. так что внешний пакет. Но 3-й уровень модификатор доступа по умолчанию уже означает " package-private". Таким образом, модификатор частного доступа 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, но мы не знаем. Так что защищенный не может использовать полный потенциал(основной объем подкласс-wide) в верхнем уровне, который является внешним пакетом (т. е. нет такой подпакетной вещи), но защищен может использовать полный потенциал во вложенном классе, который является внешним классом (т. е. может быть подклассом):

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

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

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

enter image description here

если 1-й уровень(public) и 3-й уровень (package-private) разрешены, как на земле между 2-м уровнем (protected) не допускается ?

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

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

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

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

enter image description here

как мы видим теперь, как protected и package-private теперь находятся на одном уровне (Y-Y-N), нет больше путаницы о том, почему между уровня не допускается. В целом, Java pick only package-private over protected, чтобы избежать путаницы(это просто вопрос выбора, но защищены основная характеристика является подклассом, поэтому package-private превосходит), а результат, только 2 модификатора доступа разрешены на верхнем уровне:

на верхнем уровне-public, или пакет-частный (без явного модификатора).

Protected не похож на public. Protected имеет доступ к обоим пакетам уровня плюс может быть доступен за пределами пакетов только по наследованию..Если класс говорит, что A вне пакета наследует класс от другого пакета (с защищенным методом с помощью наследования), он может получить доступ к методам этого класса 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
}

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

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

защищенный: виден только на уровне пакета*.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

protected means that the member can be accessed by any class in the same package 
and by sub classes even if they are in another packages.
example:
    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 
    }