Why can a class not be defined as protected?

JavaClassProtected

Java Problem Overview


Why can we not define a class as protected?

I know that we can't, but why? There should be some specific reason.

Java Solutions


Solution 1 - Java

Because it makes no sense.

Protected class member (method or variable) is just like package-private (default visibility), except that it also can be accessed from subclasses.
Since there's no such concept as 'subpackage' or 'package-inheritance' in Java, declaring class protected or package-private would be the same thing.

You can declare nested and inner classes as protected or private, though.

Solution 2 - Java

As you know default is for package level access and protected is for package level plus non-package classes but which extends this class (Point to be noted here is you can extend the class only if it is visible!). Let's put it in this way:

  • protected top-level class would be visible to classes in its package.
  • now making it visible outside the package (subclasses) is bit confusing and tricky. Which classes should be allowed to inherit our protected class?
  • If all the classes are allowed to subclass then it will be similar to public access specifier.
  • If none then it is similar to default.

Since there is no way to restrict this class being subclassed by only few classes (we cannot restrict class being inherited by only few classes out of all the available classes in a package/outside of a package), there is no use of protected access specifiers for top level classes. Hence it is not allowed.

Solution 3 - Java

public class A
{
    protected class B
    {
    }
}

Solution 4 - Java

Defining a field protected makes that field accessible inside the package as well as outside the package through inheritance only (Only inside the child class).

So If we are allowed to make a class protected then we can access it inside the package very easily but for accessing that class outside of the package we first need to extend that entity in which this class is defined which is its package.

And since a package can not be extended (can be imported), defining a class protected will again make it package-private which is similar to defining it as default which we can already do. Therefore there is no benefit of defining a class private it will only make things ambiguous.

For more information read Why an outer Java class can’t be private or protected

Solution 5 - Java

@Nikita Rybak answer has good points but lack of details, i can't simply get the idea without think deeply myself, the following is what i thought and now i should completely understood the reason.

Four access modifiers, assume the 1st level is public and 4th level is private (based on this table in sequence). The first thing we should know is why class cannot defined as private in top-level.

So if "private class foo"(A private member defined, i.e. class itself is a member) allow, what is the outer (which contains the member) ? File scope ? No, file outer is pointless because even multiple classes in single file will be compile into separate class files. So the outer is package. But the 3rd level default access modifier already means "package-private". So the 4th level private access modifier will not be used/allowed.

But nested private class is allow because the direct outer is class, not package, e.g.:

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

Now what if "protected class foo" allow ? protected main characteristic is subclass, so the outer(package) SHOULD(due to up-to scope, but still it's optional) provide style of subclass, i.e. sub-package, or package A extends package B, but we know no such thing. So protected can't use full potential(main scope is subclass-wide) in top-level which the outer is package(i.e. no such sub-package thing), but protected can use full potential in nested class which the outer is class(i.e. can be subclass):

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

Note that the above said "can't use full potential" due to it can't reach subclass-wide merely because no outer subclass, that's means actually protected can be allow, it's just a matter of choice to avoid duplicate the job of package-private if outer not subclass-able, see below.

My confusing is mainly caused by the famous table at https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html:

enter image description here

If 1st level(public) and 3rd level (package-private) allowed, how on earth the in-between 2nd level (protected) not allowed ?

public support subclass so easy to misleading. The correct way to read this table is

> public support subclass if the outer has subclass feature.

The same misleading apply to package-private, package-private doesn't support subclass (N in cell) doesn't means subclass concept apply in outer.

That's means we should ignore the Subclass column if subclass feature is not available in outer:

enter image description here

As we can see now, both protected and package-private are the same level now (Y-Y-N), no more confusion about why in-between level is not allowed. Overall, Java pick only package-private over protected to avoid confusing(it's just a matter of choice, but protected main characteristic is subclass, so package-private is superior), and the result, only 2 access modifiers allowed in top-level:

> At the top level—public, or package-private (no explicit modifier).

Solution 6 - Java

Protected is not similar to public. Protected has both package level access plus can be accessed outside of packages only by inheritance..If a class say A outside a package INHERITS a class from other package(with protected method by using INHERITANCE) it can access the methods of this class B which has protected methods but the sub-classes derived from this class i.e., A can't access the protected methods..the opposite happens with public..

Example:

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
}

Solution 7 - Java

if a outer class is declared by protected, I think you want the class can be only accessed from same package and its subclass but different packages. However, there is no possible to create subclasses for a protected class, because when you write "class Dog extends Animal", because of protected "Animal" only can be accessed by its subclass, obviously, "Dog" is not "Animal" subclass.

So protected outer class is same with (default) outer class!

Solution 8 - Java

behavior of “protected” = behavior of “default”+ “use it in any subclass in any package”.

Anyway we have default access modifier for class, only advantage we can get from protected access modifier is:- by using it in any package through subclassing. But for subclass, visibility of parent “protected”class would be private. So it can’t be accessed. Basically if you have a protected top-level class, no outer class can gain access by subclassing it. So protected for a top-level class is meaningless.

Solution 9 - Java

Protected : VISIBLE only to package level*.

class is defined protected ---> it cannot be extended from outside package(not visible).

And if it cannot be extended then it is meaningless to keep it as protected, because then it will become default access which is allowed.

Same applies to private defined classes.

Note : Nested or inner classes can be defined protected or private.

* : Explore protected keyword, for this answer I made it succinct.

Solution 10 - Java

The answer from @Akash5288 made no sense to me:

> If all the classes are allowed to subclass then it will be similar to public access specifier. > >Since there is no way to restrict this class being subclassed by only few classes (we cannot restrict class being inherited by only few classes out of all the available classes in a package/outside of a package), there is no use of protected access specifiers for top level classes. Hence it is not allowed.

You can then apply the same logic to protected methods and variables, they are also then "similar to public". All classes outside of a package can extend our public class and use its protected methods. Why is restricting methods and variables to extended classes ok, but restricting the whole class not ok? "Similar to public" is not "same as public". My interpretation is that it is perfectly fine to allow a protected class, as it is fine to allow protected methods.

The answer "you can not extend a class you can not access/see" is more logical.

Solution 11 - Java

What makes sense to this question is that, JVM is written in C (Sun JVM) and C++(oracle JVM) so during compilation, we are going to create .class files out of our java file and if we declare a class with Protected keyword then it will not be accessed by JVM.

The answer why protected class will not be accessed by JVM is that, since protected fields are accessible within same package or to diffrent package through inheritance only and JVM is not written in a way so that it will inherit will class. Hope this satisfies this question :)

Similarly, A top level class can't be private. Explanation as below:

So what will happen if we will define a class private, that class will only be accessible within the entity in which it is defined which in our case is its package?

So defining private access to the class will make it accessible inside the same package which default keyword already do for us, Therefore there is no benefit of defining a class private it will only make things ambiguous.

Solution 12 - Java

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 
}

Solution 13 - Java

The protected modifier is allowed on an inner class. But still an instance of this inner class cannot be constructed from within a class extending the outer class. Only when the constructing code is within the same package it is allowed by the compiler. But what difference does the protected modifier then make with respect to the default accessibility? So, from my point of view, the protected modifier is not at all allowed on top-level classes, and it does not make sense on embedded classes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionM.J.View Question on Stackoverflow
Solution 1 - JavaNikita RybakView Answer on Stackoverflow
Solution 2 - JavaAkash5288View Answer on Stackoverflow
Solution 3 - JavairreputableView Answer on Stackoverflow
Solution 4 - JavaNaresh JoshiView Answer on Stackoverflow
Solution 5 - Java林果皞View Answer on Stackoverflow
Solution 6 - JavaShruthi reddyView Answer on Stackoverflow
Solution 7 - JavaJeen YungView Answer on Stackoverflow
Solution 8 - JavamadhuView Answer on Stackoverflow
Solution 9 - JavaNarendra SinghView Answer on Stackoverflow
Solution 10 - Javak-sView Answer on Stackoverflow
Solution 11 - JavaAnurag PrasadView Answer on Stackoverflow
Solution 12 - JavaYogesh PatilView Answer on Stackoverflow
Solution 13 - JavaGregorView Answer on Stackoverflow