Why can we not define a class as protected?
I know that we can't, but why? There should be some specific reason.
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.
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.
public class A
{
protected class B
{
}
}
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
#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:
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:
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).
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
}
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!
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.
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.
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.
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.
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
}
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.
public class A
{
public static void main(String args[])
{
}
}
class B
{
private static void call
{
int x=9;
String name ="hello";
}
}
Can anyone please tell me how to access class B private method fields in class A and print them in class A.
Thank u..
You can access private fields and methods in other classes, but the whole point is that you're not supposed to. They're private.
So the correct thing to do is make them available to other classes by making them public. In the case of fields (rather than methods), you might do that with accessor methods.
But, if you really had to access private fields or methods, you can do it via java.lang.reflect.
// Calling the static `call` method of `B` even though it's private:
Method m = B.class.getMethod("call");
m.setAccessible(true);
m.invoke(null);
But again, you shouldn't do this without a really good reason. Fix the design instead.
We Should Not try to access directly the private members of a class in another class. This will altogether violate the rule of Access Modifiers. Moreover if you really want to access, you can make use of Reflection API provided.
Generally, in order to get the private class variables, you can create public setters and getters in order to access then outside that class.
By design you cannot. Revise the class so the method you want to call is visible to A.
That said, you can use reflection to access methods, fields etc inside B, but you cannot easily just do it with "B.call()" which most likely is what you would like to do.
I know that subclass has no access to private field other than with public setter/getter of super-class. I do not have any experience with object-oriented languages so far. Should I make all fields private and just use public method to access them in sub-classes, or make them protected and use the freely in subclasses and package?
Make them protected. This is the sole purpose why this keyword exists!
In OOP there is a feature encapsulation and encapsulation strongly suggest us to hide data from the outer world. And you can hide data by making field/property/variable private.
And for accessing the private variable use some public getter method.
it depends on your needs. If you need access to subclass as well as the same package, make it protected.
Here are the general rules:
private: class access only.
protected: package access and also derived classes.
default: same package only.
public: anyone can access it.
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
A nested class has access to all the private members of its enclosing
class—both fields and methods. Therefore, a public or protected nested
class inherited by a subclass has indirect access to all of the
private members of the superclass.
See the Java Tutorial
I wonder if it's okay (not considered bad practice) to have public members in package private class. I tend to add public keyword to members of my default visibility classes to indicate that such members are part of the classes API.
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Example:
class ModuleImplementationClass {
private int fieldA;
private String fieldB;
private void someClassInternalMethod() {
// impl
}
public int doSth() {
// method that will be called by other classes in the package
}
}
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Well that depends. Not if you're overriding existing methods (e.g. toString()) or implementing an interface.
If you don't want the method to be used from outside the package, make it package private. If you're happy for it to be used from anywhere, make it public. Or another way to think about it: design your method access so that if someone changed just the class access to make it a public class, you wouldn't want to change the method access too.
I have been working with android for a few years now, not once have I had a teacher or anyone to tell me what to do.
This whole time I have wondered to myself this.
When you have a method I generally see...
public void method(){
//Stuff
}
or
private void method(){
//stuff
}
I know that a void is a method with no return value, and that public is the visibility of the method in a way but would it matter if I just used something like this...
void method(){
//stuff
}
Because then the methods visibility would just be default anyway?
I have no idea if I am right or not, is it just good practice to specify "public" or "private" ?
Not specifying anything has a specific meaning:
public - any class can access this member
protected - subclasses can access this member (as well as code in the same class or in the same package)
private - only code in the same class can access this member
nothing ("default" access) - only code in the same package can access this member
Arguably the last case should have had its own keyword, but we're stuck with it now. Unless you really mean to use default visibility, it's poor form to not specify anything - did you really need package visibility for some reason, or did you just default to package visibility for everything? Best practice is to explicitly use private for non-public members unless you need one of the others.
Java has four levels of visibility: public, protected, (default), private
Visible to the package. the default. No modifiers are needed.
Visible to the class only (private).
Visible to the world (public).
Visible to the package and all subclasses (protected).
Default Access Modifier - No keyword:
Default access modifier means we do not explicitly declare an access
modifier for a class, field, method etc.
A variable or method declared without any access control modifier is
available to any other class in the same package. The default modifier
cannot be used for methods, fields in an interface.
Private Access Modifier - private:
Methods, Variables and Constructors that are declared private can only
be accessed within the declared class itself.
Private access modifier is the most restrictive access level. Class
and interfaces cannot be private.
Variables that are declared private can be accessed outside the class
if public getter methods are present in the class.
Using the private modifier is the main way that an object encapsulates
itself and hide data from the outside world.
Public Access Modifier - public:
A class, method, constructor, interface etc declared public can be
accessed from any other class. Therefore fields, methods, blocks
declared inside a public class can be accessed from any class
belonging to the Java Universe.
However if the public class we are trying to access is in a different
package, then the public class still need to be imported.
Because of class inheritance, all public methods and variables of a
class are inherited by its subclasses.
Protected Access Modifier - protected:
Variables, methods and constructors which are declared protected in a
superclass can be accessed only by the subclasses in other package or
any class within the package of the protected members' class.
The protected access modifier cannot be applied to class and
interfaces. Methods, fields can be declared protected, however methods
and fields in a interface cannot be declared protected.
Protected access gives the subclass a chance to use the helper method
or variable, while preventing a nonrelated class from trying to use
it.
Java has four levels of visibility: public, protected, (default), private. The meaning of these is as follows:
public - makes your methods accessible to any other class.
protected - makes your methods accessible to any class in the same package OR any subclass of your class.
(default, i.e. no modifier) - makes your methods accessible only to classes in the same package.
private - makes your methods accessible only to the current class.
The same rules apply when specifying the access modifiers on classes, methods and fields.