Understanding Java's protected modifier - java

I have a class called A in package1 and another class called C in package2. Class C extends class A.
A has an instance variable which is declared like this:
protected int protectedInt = 1;
Here is the code for class A
package package1;
public class A {
public int publicInt = 1;
private int privateInt = 1;
int defaultInt = 1;
protected int protectedInt = 1;
}
And here is the code for class C:
package package2;
import package1.A;
public class C extends A{
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
}
Eclipse underlines the last line in C.go() and says "A.protectedInt" is not visible. It seems that this conflicts with the definition of the "protected" keyword, given the Oracle documentation says:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
What's going on here?

What's going on here?
You've misunderstood the meaning of protected. You can access the protected members declared in A from within C, but only for instances of C or subclasses of C. See section 6.6.2 of the JLS for details of protected access. In particular:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
[...]
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
(Emphasis mine.)
So this code would be fine:
C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);

Since C is inheriting A, C can directly use the protected variable of A like below
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
As per your code, you are creating an instance of A and accessing protected variable through that instance, which violates java's rule - A protected variable is not visible outside the package

Protected means:
a) This member will be accessible to all classes in the same package through A object’s reference.
b) For different packages, this will be accessible only inside subclasses of A, say B, and the reference used can be a B instance or of any subclass of B.
Let's take an example:
Let A be a parent class in some package, say com.ex1.
Let B and C be classes in different packages w.r.t to A, say com.ex2. Also, B extends A and C extends B.
We will see how we can use protected fields of A inside B (a subclass of A).
A's code:
public class A {
protected int a = 10;
}
B's code:
public class B extends A {
public void printUsingInheritance() {
// Using this
System.out.println(this.a);
}
public void printUsingInstantiation() {
// Using instance of B
B b = new B();
System.out.println(b.a);
// Using instance of C as C is a subclass of B
C c = new C();
System.out.println(c.a);
A a = new A();
System.out.println(a.a); // Compilation error as A is not a subclass of B
}
}
C's code:
public class C extends B {
}
For protected static:
Same rules apply except that in b) now it is accessible in any subclass of A by A's class reference. Reference

public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
When you are doing A a = new A(); and a.protectedInt you trying to access protected member of A which is illegal according to java standards
Instead you can do this.protectedInt directly.

No need to instantiate Protection class inside Protection2 Class. You can directly call the protected variable without instantiating the Protection class. Because Protection2 class extends Protection class. So variable automatically inherited by subclass.
Try with below code:
public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}

Within the same package where the protected member is declared, access is permitted:
package package1;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // got printed
C c = new C();
System.out.println(c.protectedInt); // got printed as well
}
}
Outside the package where the protected member is declared, access is permitted if and only if by code that is responsible for the implementation of that object. In this case, C is responsible for the implementation of that object, so it could access the protected.
package package2;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // compiler complains
C c = new C();
System.out.println(c.protectedInt); // got printed
}
}

Related

Java static constructor access in child class

I have two classes
package a;
public class A {
protected void doSomething() {
}
protected static class C {
protected C(int c) {
}
}
}
package b;
public class B extends A {
#Override
protected void doSomething() {
C c = new C(0); //compile error
C c2 = new C(0){}; //legal
}
}
I have read chapter 6.6.2.2. Access to a protected Constructor of JLS (https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html) but i am still confused with the explanation. What is wrong with the call of the super constructor new C(0); even if B is a child of A?
Thank you :-)
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.
Now, the constructor of C class is protected therefore is accessible outside the a package only by subclasses of C. But B is not a subclass of C ...
As #Amongalen pointed out, the second statement
C c2 = new C(0){};
is legal because it creates an anonymous class that extends C, therefore the protected constructor is visible here.

Protected access across package through reference variable in java [duplicate]

I have a class called A in package1 and another class called C in package2. Class C extends class A.
A has an instance variable which is declared like this:
protected int protectedInt = 1;
Here is the code for class A
package package1;
public class A {
public int publicInt = 1;
private int privateInt = 1;
int defaultInt = 1;
protected int protectedInt = 1;
}
And here is the code for class C:
package package2;
import package1.A;
public class C extends A{
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
}
Eclipse underlines the last line in C.go() and says "A.protectedInt" is not visible. It seems that this conflicts with the definition of the "protected" keyword, given the Oracle documentation says:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
What's going on here?
What's going on here?
You've misunderstood the meaning of protected. You can access the protected members declared in A from within C, but only for instances of C or subclasses of C. See section 6.6.2 of the JLS for details of protected access. In particular:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
[...]
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
(Emphasis mine.)
So this code would be fine:
C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
Since C is inheriting A, C can directly use the protected variable of A like below
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
As per your code, you are creating an instance of A and accessing protected variable through that instance, which violates java's rule - A protected variable is not visible outside the package
Protected means:
a) This member will be accessible to all classes in the same package through A object’s reference.
b) For different packages, this will be accessible only inside subclasses of A, say B, and the reference used can be a B instance or of any subclass of B.
Let's take an example:
Let A be a parent class in some package, say com.ex1.
Let B and C be classes in different packages w.r.t to A, say com.ex2. Also, B extends A and C extends B.
We will see how we can use protected fields of A inside B (a subclass of A).
A's code:
public class A {
protected int a = 10;
}
B's code:
public class B extends A {
public void printUsingInheritance() {
// Using this
System.out.println(this.a);
}
public void printUsingInstantiation() {
// Using instance of B
B b = new B();
System.out.println(b.a);
// Using instance of C as C is a subclass of B
C c = new C();
System.out.println(c.a);
A a = new A();
System.out.println(a.a); // Compilation error as A is not a subclass of B
}
}
C's code:
public class C extends B {
}
For protected static:
Same rules apply except that in b) now it is accessible in any subclass of A by A's class reference. Reference
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
When you are doing A a = new A(); and a.protectedInt you trying to access protected member of A which is illegal according to java standards
Instead you can do this.protectedInt directly.
No need to instantiate Protection class inside Protection2 Class. You can directly call the protected variable without instantiating the Protection class. Because Protection2 class extends Protection class. So variable automatically inherited by subclass.
Try with below code:
public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
Within the same package where the protected member is declared, access is permitted:
package package1;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // got printed
C c = new C();
System.out.println(c.protectedInt); // got printed as well
}
}
Outside the package where the protected member is declared, access is permitted if and only if by code that is responsible for the implementation of that object. In this case, C is responsible for the implementation of that object, so it could access the protected.
package package2;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // compiler complains
C c = new C();
System.out.println(c.protectedInt); // got printed
}
}

Java-OOP: Why Java hides protected methods from super class instance in sub class? [duplicate]

I have a class called A in package1 and another class called C in package2. Class C extends class A.
A has an instance variable which is declared like this:
protected int protectedInt = 1;
Here is the code for class A
package package1;
public class A {
public int publicInt = 1;
private int privateInt = 1;
int defaultInt = 1;
protected int protectedInt = 1;
}
And here is the code for class C:
package package2;
import package1.A;
public class C extends A{
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
}
Eclipse underlines the last line in C.go() and says "A.protectedInt" is not visible. It seems that this conflicts with the definition of the "protected" keyword, given the Oracle documentation says:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
What's going on here?
What's going on here?
You've misunderstood the meaning of protected. You can access the protected members declared in A from within C, but only for instances of C or subclasses of C. See section 6.6.2 of the JLS for details of protected access. In particular:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
[...]
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
(Emphasis mine.)
So this code would be fine:
C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
Since C is inheriting A, C can directly use the protected variable of A like below
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
As per your code, you are creating an instance of A and accessing protected variable through that instance, which violates java's rule - A protected variable is not visible outside the package
Protected means:
a) This member will be accessible to all classes in the same package through A object’s reference.
b) For different packages, this will be accessible only inside subclasses of A, say B, and the reference used can be a B instance or of any subclass of B.
Let's take an example:
Let A be a parent class in some package, say com.ex1.
Let B and C be classes in different packages w.r.t to A, say com.ex2. Also, B extends A and C extends B.
We will see how we can use protected fields of A inside B (a subclass of A).
A's code:
public class A {
protected int a = 10;
}
B's code:
public class B extends A {
public void printUsingInheritance() {
// Using this
System.out.println(this.a);
}
public void printUsingInstantiation() {
// Using instance of B
B b = new B();
System.out.println(b.a);
// Using instance of C as C is a subclass of B
C c = new C();
System.out.println(c.a);
A a = new A();
System.out.println(a.a); // Compilation error as A is not a subclass of B
}
}
C's code:
public class C extends B {
}
For protected static:
Same rules apply except that in b) now it is accessible in any subclass of A by A's class reference. Reference
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
When you are doing A a = new A(); and a.protectedInt you trying to access protected member of A which is illegal according to java standards
Instead you can do this.protectedInt directly.
No need to instantiate Protection class inside Protection2 Class. You can directly call the protected variable without instantiating the Protection class. Because Protection2 class extends Protection class. So variable automatically inherited by subclass.
Try with below code:
public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
Within the same package where the protected member is declared, access is permitted:
package package1;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // got printed
C c = new C();
System.out.println(c.protectedInt); // got printed as well
}
}
Outside the package where the protected member is declared, access is permitted if and only if by code that is responsible for the implementation of that object. In this case, C is responsible for the implementation of that object, so it could access the protected.
package package2;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // compiler complains
C c = new C();
System.out.println(c.protectedInt); // got printed
}
}

Access Modifier(Protected Keyword) in Java [duplicate]

I have a class called A in package1 and another class called C in package2. Class C extends class A.
A has an instance variable which is declared like this:
protected int protectedInt = 1;
Here is the code for class A
package package1;
public class A {
public int publicInt = 1;
private int privateInt = 1;
int defaultInt = 1;
protected int protectedInt = 1;
}
And here is the code for class C:
package package2;
import package1.A;
public class C extends A{
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
}
Eclipse underlines the last line in C.go() and says "A.protectedInt" is not visible. It seems that this conflicts with the definition of the "protected" keyword, given the Oracle documentation says:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
What's going on here?
What's going on here?
You've misunderstood the meaning of protected. You can access the protected members declared in A from within C, but only for instances of C or subclasses of C. See section 6.6.2 of the JLS for details of protected access. In particular:
Let C be the class in which a protected member is declared. Access is permitted only within the body of a subclass S of C.
In addition, if Id denotes an instance field or instance method, then:
[...]
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
(Emphasis mine.)
So this code would be fine:
C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
Since C is inheriting A, C can directly use the protected variable of A like below
public class C extends A{
public void go(){
System.out.println(protectedInt);
}
}
As per your code, you are creating an instance of A and accessing protected variable through that instance, which violates java's rule - A protected variable is not visible outside the package
Protected means:
a) This member will be accessible to all classes in the same package through A object’s reference.
b) For different packages, this will be accessible only inside subclasses of A, say B, and the reference used can be a B instance or of any subclass of B.
Let's take an example:
Let A be a parent class in some package, say com.ex1.
Let B and C be classes in different packages w.r.t to A, say com.ex2. Also, B extends A and C extends B.
We will see how we can use protected fields of A inside B (a subclass of A).
A's code:
public class A {
protected int a = 10;
}
B's code:
public class B extends A {
public void printUsingInheritance() {
// Using this
System.out.println(this.a);
}
public void printUsingInstantiation() {
// Using instance of B
B b = new B();
System.out.println(b.a);
// Using instance of C as C is a subclass of B
C c = new C();
System.out.println(c.a);
A a = new A();
System.out.println(a.a); // Compilation error as A is not a subclass of B
}
}
C's code:
public class C extends B {
}
For protected static:
Same rules apply except that in b) now it is accessible in any subclass of A by A's class reference. Reference
public void go(){
//remember the import statement
A a = new A();
System.out.println(a.publicInt);
System.out.println(a.protectedInt);
}
When you are doing A a = new A(); and a.protectedInt you trying to access protected member of A which is illegal according to java standards
Instead you can do this.protectedInt directly.
No need to instantiate Protection class inside Protection2 Class. You can directly call the protected variable without instantiating the Protection class. Because Protection2 class extends Protection class. So variable automatically inherited by subclass.
Try with below code:
public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
Within the same package where the protected member is declared, access is permitted:
package package1;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // got printed
C c = new C();
System.out.println(c.protectedInt); // got printed as well
}
}
Outside the package where the protected member is declared, access is permitted if and only if by code that is responsible for the implementation of that object. In this case, C is responsible for the implementation of that object, so it could access the protected.
package package2;
public class C extends A{
public void go(){
A a = new A();
System.out.println(a.protectedInt); // compiler complains
C c = new C();
System.out.println(c.protectedInt); // got printed
}
}

Why have I no access to the protected field?

I am learning about access levels in java and I have created 3 classes:
In package my.inheritance
I have class A and class C
package my.inheritance;
public class A {
protected int a=15;
}
package my.inheritance;
public class C {
public static void main(String[] args)
{
A a = new A();
System.out.println(a.a);
}
}
And in another package called my.inheritance.test I have a class B trying to access protected field of int value a but the compiler complains for this!
package my.inheritance.test;
import my.inheritance.A;
public class B extends A{
public static void main(String[] args)
{
A a = new A();
int value = a.a;
System.out.println(value);
}
}
I was under the impression with protected you can access a member from a different class in a different package as long as you subclass it! Why the visibility error then ?
Every method can access protected fields of its own class, and all its parent classes. This does not include access to protected fields of another class, even if they have the corresponding base class in common.
So methods in class B can access protected fields from objects of class B, even if they were declared in A, but not from some other object of class A.
One could say that class B inherits the protected members from A, so now every B has those members as well. It doesn't inherit access to the protected members of A itself, so it cannot operate on protected members of any A but only on those of B, even if they were inherited from A.
Try:
public class B extends A
{
public static void main(String[] args)
{
B a = new B();
int value = a.a;
System.out.println(value);
}
}
You can access a only if it is in the same object.
1. protected is an access modifier which is used when you want to have an access outside the package.
2. Most people try to access the protected member of the Super class by creating and Object reference variable of the Super class, and then using dot operator to access that protected member.... But thats WRONG.
3. We get access to the inherited member of the Super class Not the direct member of the super class.
Eg:
package com.demo1;
public class A{
protected int a = 5;
}
package com.demo2;
public class B extends A{
public static void main(String[] args){
System.out.println(new B().a); // This "a" is the inherited member
}
}
4. And one more important point, This inherited "a" member in the sub-class, will be seen by the another class in the same package that of the sub-class as a private member.. So consider that another class in this package can't even see this protected memeber...
You have access to this field from B using this.a because B extends A, but in this case you are trying to access to this field througth an instance of A, this is limited by the protected access.
What you're trying to do is:
A a = new A();
int value = a.a;
Note that a.a is a qualified name, and in this case you can call it in body of a class B only if the type of the expression to the left of . is B or it's subclass.
Relevant part of JLS

Categories