Members Access Modifiers

0

In my last article, I showed you examples of class level access modifiers. In this article, I will cover member level access modifiers. Before I start with the examples, I would like to first define what is accessibility and the various access modifiers that a member can use.

What is member accessibility?

If class A has access to a member of class B, it means that class B's member is visible to class A and A will be able to invoke it.

There are three ways to access a method:

  • When a method in one class tries to access a method or a variable of another class using a reference of the class
  • When a class sub-classes another class, it may be able to inherit its super class’s method
  • Last one is simple – Invoking a method declared in the same class

In the last article, I showed you that a class can use only public or default access modifier.

You can declare classes with protected or private access modifier  but they have to be declared within the scope of a public or default class.

Access Modifiers available to a member

Unlike class, a member can use all four access modifiers.  Assuming class A is visible to class B, types of access control are:

  •  public

When a member is declared public, it means all other classes, regardless of the package they belong to, can access the member

  • package (default)

A default member may be accessed only if the class accessing the member belongs to the same package.

  • protected

A protected member is accessible from the classes within the same package. If the class is in a different package then it can access the protected member only through inheritance by sub-classing the  class owning the protected member. But still it can’t invoke the member through the reference.

  • private

A private member is accessible only to the class owning the method.

Class Visibility

If the class itself will not be visible to another class, then none of the members will be visible, even if the member is declared public.

Let me now show you an example for each of the access modifier. We will start with the public access modifier.

Public member

A public method can be invoked from any class, provided the class itself is visible to the class invoking the method.

Example: Class A has a public method publicMethodA().

It can be invoked from within its own code. In the below example, method doSomething() creates an instance of A and then calls publicMethodA().
It can also invoke publicMethodA() on the current instance using this.publicMethodA() or simply publicMethodA()

package javarticles.pkgone;

import javarticles.pkgtwo.E;

public class A  {
    public void publicMethodA() {
    }
    public void doSomething() {
        A a = new A();
        a.publicMethodA();
        this.publicMethodA();
    }
}

It can also be accessed from a class in a different package, for example, class D located in package javarticles.pkgtwo. Since it extends class A, it can invoke the method on this as well as on a reference a.publicMethodA().

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    public void doSomething() {
        publicMethodA();
        A a = new A();
        a.publicMethodA();
    }
}

Now we will come to the trickier part.

Protected and Default members

There is one simple rule for the default (package) member. A package member can be accessed only if the class accessing it belongs to the same package.
For example, we have class A with a default member packageMethodA(). It can be accessed from within class A as well as from class B from the same package:

package javarticles.pkgone;

import javarticles.pkgtwo.E;

public class A {
    void packageMethodA() {
    }

    public void doSomething() {
        A a = new A();
        a.packageMethodA();
        packageMethodA();
    }
}
package javarticles.pkgone;

public class B {
    public void doSomething() {
        A a = new A();
        a.packageMethodA();
    }
}

When class D from a different package tries to access A's default member packageMethodA(), compiler will issue an error:

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    public void doSomething() {
        A a = new A();
        a.pakageMethodA();
        packageMethodA();        
    }
}

The method pakageMethodA() from the type A is not visible

A class within the same package as protected member’s class can access the package as well as protected members. It doesn’t need to sub-class the class to access the protected members.
If the class is in a different package it can access the protected member only through inheritance by sub-classing the class owning the protected member.
It cannot access it through the reference.

Example: class A contains a protected method protectedMethodA().  As usual, irrespective of the access modifier it can be accessed from the code within the same class.

package javarticles.pkgone;

import javarticles.pkgtwo.E;

public class A {
    protected void protectedMethodA() {
    }

    public void doSomething() {
        A a = new A();
        a.protectedMethodA();
        protectedMethodA();
    }
}

Class B which is in the same package can also access the protected method.

package javarticles.pkgone;

public class B {
    public void doSomething() {
        A a = new A();
        a.protectedMethodA();
    }
}

Class D which is a sub-class of A and is in a different package can access protectedMethodA() only through inheritance.

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    public void doSomething() {
        protectedMethodA();
        A a = new A();
        //uncomment, compilation  will fail with error - protected method can't be accessed through reference
        //a.protectedMethodA();        
    }
}

It can’t access the protected method through reference like a.protectedMethodA(). If tried, compiler will issue an error:
protected method can’t be accessed through reference

Private member

A private member is only accessible from the class in which it was declared.
For example, if class A has a private member privateMethodA(), it can be accessible only from the code within class A. You can invoke it directly on the current instance this or through a reference like a.privateMethodA()

package javarticles.pkgone;

public class A extends E {
    private void privateMethodA() {
    }
    
    public void doSomething() {
        A a = new A();
        a.privateMethodA();
        privateMethodA();
    }
}

Any other class irrespective of the package, won’t be able to access the private method. Below shows class C which is a sub-class of A and from the same package, trying to access the private method.

package javarticles.pkgone;
public class C extends A {
    public void doSomething() {
        A a = new A();        
        a.privateMethodA();
        packageMethodA();
    }
}

Compiler issues an error:
The method privateMethodA() from the type A is not visible

When a member is declared private, a subclass can’t inherit it. You can, however, declare a matching method in the subclass. Declaring a method with same name as its parent’s private method is not overriding method and will be treated as a new method.

For example, class D below declares privateMethodA(). Irrespective of its access modifier, it will be treated as different method.

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    //will be treated as a different method and won't be considered as overridden.
    public void privateMethodA() {        
    }
}

When you are sub-classing there is chance that you may modify the accesses modifier.  For example, class D tries to override A's public method publicMethodInA() but changes the access modifier to private.

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    //compiler error Cannot reduce the visibility of the inherited method from A
    private void publicMethodA() {
    }    
}

Compiler issues error: Cannot reduce the visibility of the inherited method from A

You cannot reduce the visibility of a method by overriding and reducing its scope.

Suppose if D which is a different package tries to override A's package method packageMethodInA(), it will be treated as a new method. It won’t be considered as overriding a method as the package method of A was never visible to D in the first place.

package javarticles.pkgtwo;

import javarticles.pkgone.A;

public class D extends A {
    void packageMethodA() {
    } 
}

Compiler will issue a warning though: The method D.packageMethodA() does not override the inherited method from A since it is private to a different package

A sub-class may want to improve the visibility of a method, for example, class C overrides the package method packageMethodA() and modify its access modifier from default to protected. This is allowed as it improves the visibility.

package javarticles.pkgone;

public class C extends A {
    //improve visibility from package to protected
    protected void packageMethodA() {
    }        
}

Now we will see the converse,  class C tries to override A's protected method protectedMethodA() and modifies its access modifier from protected to the default one.

package javarticles.pkgone;

public class C extends A {
    //can't change protected to package
    //uncomment below, compiler will fail - Cannot reduce the visibility of the inherited method from A
    void protectedMethodA() {
    }     
}

Compiler issues error: Cannot reduce the visibility of the inherited method from A

Before I end this article, let me show you an example of a class is trying to use the subclass-outside-the-package to get to the subclass’ inherited protected superclass member. Will it able to access the protected member?

For example, Class E has a protected variable eVar. Class A from a different package extends Class E.
Class A can access E's protected variable aVar.
Class C which extends class A can access the protected variable as it is in the same hierarchy.

But class B which is in the same package as A's won’t be able to access E's protected variable eVar as B is not in E's package. It will only be able to access the protected and package members of A but not E.

Rule is once the subclass-outside-the-package inherits the protected member, that member (as inherited by the subclass) becomes private to any code outside the subclass, with the exception of subclasses of the subclass.

Below diagram explains the scenario:
protected_var_access_from_different_pkg

 

 

The table below is a nice summary of the examples I have shown you.

Combination of visibility and accessibility

Visibility Public Protected Default Private
From the same class Y Y Y Y
From any class in the same package Y Y Y N
From a subclass in the same package Y Y Y N
From a subclass outside the same package Y Y, through inheritence N N
From any non-subclass class outside the package Y N N N

Download source code here

Share.

Leave A Reply