2

I was given a question to determine whether the following access is legal.

package SomePack;

public class A1 {
    ...
protected int y1;
}

///////////

package Whatever;
class B2 extends A1 {
    void h(SomePack.A1 x) {
        x.y1 = 3; // Is this line legal?
    }
}

I thought it's presumably legal since 1. y1 field is protected 2. B2 extends A1 so B2 is a subtype of A1. 3. Access control is based on static type and the static type of x is A1.

But the interviewer said the answer should be illegal. Anyone could help explain this? Many thanks.

Tinyik
  • 457
  • 6
  • 21
  • 2
    this will help [Controlling Access to Members of a Class](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) – Lahiru Ashan Oct 17 '16 at 06:56
  • IMHO the correct interview answer was: "It does not matter it that compiles, it should not be done in the first place!" – Timothy Truckle Oct 17 '16 at 07:01

3 Answers3

0

The protected modifier is intended for inheritance, for package visibility only use no modifiers.

Here is a brief explanation of what the different visibilities are intended for

public modifier is used when visibility is needed everywhere:

public void someMethod(){
    //user code here
}

protected modifier is used when you want the content of the class to be accessible through inheritance:

protected void someMethod(){
    //user code here
}

no modifier is used when you want package visibility only:

void someMethod(){
    //user code here
}

Lastly private is for when you want no visibility and only want to use it internally.

private void someMethod(){
    //user code here
}

For a more detailed explanation of the above I would refer to: Controlling Access to Members of a Class

Simon Jensen
  • 488
  • 1
  • 3
  • 19
0

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

see https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.1

Example 6.6-1. Access Control:

package points;
public class Point {
    protected int x, y;
    public void move(int dx, int dy) { x += dx; y += dy; }
    public int getX() { return x; }
    public int getY() { return y; }
}

The fields x and y are declared protected and are accessible outside the package points only in subclasses of class Point, and only when they are fields of objects that are being implemented by the code that is accessing them.

So in class B2, it can access y1 of itself or object of B2, but cannot access y1 of SomePack.A1 x or object of any other A1's subclass.

locoyou
  • 1,697
  • 1
  • 15
  • 19
  • Thanks. How to interpret this sentence: `and only when they are fields of objects that are being implemented by the code that is accessing them. ?` – Tinyik Oct 17 '16 at 08:42
  • @FongTinyik it means `x` and `y` are accessible outside the package if the code that uses `x` and `y` is also the code that implements the corresponding subclass. – locoyou Oct 17 '16 at 09:01
  • Code implementing `corresponding subclass` can only access `x`, `y` of (objects of) the `corresponding subclass` also. – locoyou Oct 17 '16 at 09:03
  • So inside `SubPoint` we can only access `this.x` or the `x` of other instances o `SubPoint`. Correct? – Tinyik Oct 17 '16 at 09:06
  • @FongTinyik yes. But cannot access `Point.x` of `SubPoint2.x` – locoyou Oct 17 '16 at 09:09
-1
  • A protected member is accessible outside a package only in subclass.
  • If you need to access a protected member variable outside package, it needs to be accessed only through inheritance.
  • If it needs to be accessed using reference variable, it needs to be in same package.

Following example elaborates above.

When you modify a member variable as protected, then that protected member variable is accessible outside package ONLY through inheritance.

Statement x.y1 = 3; it trying to access using reference variable which is not possible outside package.

If you want to access it simply make it y1 = 3.

Using below code should enable you to access y1

package whatever;

import somepack.A1;

class B2 extends A1 {
    void h(somepack.A1 x) {
        System.out.println(y1);
        y1 = 3; 
        System.out.println(y1);

    }

    public static void main(String args[]){
        B2 obj = new B2();
        obj.h(new A1());
    }
}

This will print below.

0
3

So as you can see we can directly assign value to protected member using inheritance only.

Now let us see how we can access using reference variable type i.e. without inheritance.

package somepack;


public class A1 {
    protected int y1;

}
class C{
    public static void main(String args[]){
        A1 obj = new A1();
        System.out.println(obj.y1);
    }

}
Prasad Kharkar
  • 13,410
  • 5
  • 37
  • 56