Saturday, December 28, 2024
Google search engine
HomeLanguagesJavaControlling the Visibility of Class and Interface in Java

Controlling the Visibility of Class and Interface in Java

Maintenance is one of the important aspects of software development, and experience has shown that software that maintains its component’s visibility low is more maintainable than one that exposes its component more. You’re not going to know it upfront, but when redesigning the application, you’re going to miss it terribly.

You end up patching and repeating the same errors, as maintaining backward compatibility is a must-have requirement for many applications. You will not do much because the class and interfaces are tightly integrated with a lot of other applications. Java has always prioritized encapsulation, providing access modifiers of support from the very beginning. By making them public, package-private or private provides ways to monitor the visibility of some type, such as class or interface.

Below are some rules to control the visibility:

  1. A top-level class (a class whose name is the same as the Java source file that contains it) can also be either a public or a private package (without an access modifier) and cannot be a private one. Private, public, or package-private may only be a nesting class.
  2. A public class is accessible to all and most visible, try to keep public only key interfaces, never let the implementation go public until you believe it’s complete and mature.
  3. The private type, on the other hand, is less visible, and in Java, only the nested class or interface can be private. You have full control over this class to change its actions with experiences, new technology, tools, and redesign, as it’s least visible.
  4. Package-private visibility is a clever midway and is also default visibility, there’s no such keyword as package-private, instead if you don’t have any access modifier as Java thinks it’s package-private, and then make it only visible on the same package.
  5. If the classes and interfaces are only shared within the same package between other classes, make them package-private. As the client is unable to reach them, they are therefore reasonably safe to change.

How to control Visibility of Class or Interface in Java?

In addition to decreasing class or interface visibility using the access modifier, based on your runtime environment, there are many other ways to do so. At the component level, such as Websphere, Weblogic, or JBoss in Application Server, an interface class may be proxied or wrapped to reduce external visibility.

No matter what you do, there will still be certain types that need to be exposed to the outside world, but you can always handle them with proxy or wrapper. Although client programs will load proxied implementation classes, an immutable proxy or wrapper would often be obtained.

For example, the Java Servlet API (javax.servlet) getServletContext() returns an implementation of javax.servlet.ServletContext, which is typically an immutable proxy to satisfy the ServletContext framework promises. It is most possible that a separate version of the javax.servlet.ServletContext specification operates on the application server.

It is possible to use a similar pattern in the implementation of other externally accessible interfaces, e.g. Javax.ejb.EJBContext, Javax.ejb.TimerService, ServletRequest, ServletResponse, etc. To support these global interfaces, various application servers can use various applications.

JDK Example of Controlling Visibility of Java Class

EnumSet class is another fascinating example of managing visibility. In order to prevent instantiation, the Java designer made the abstract class and provided factory methods as the only way to create an instance of that class, e.g. Methods from EnumSet.of() or EnumSet.noneOf().

Internally, in the form of RegularEnumSet and JumboEnumSet, they have two separate implementations, which are automatically selected based on the size of the main universe by static factory methods.

For instance, if the number of values in Enum is less than 64, then RegularEnumSet is used, otherwise, the JumboEnumSet instance is returned. The beauty of this design is that package-private means that consumers have no idea about any of these implementations.

Modifier Description
Default declarations are visible only within the package (package private)
Private declarations are visible within the class only
Protected declarations are visible within the package or all subclasses
Public declarations are visible everywhere

Private Access Modifier

Java




// Java program for showcasing the behaviour
// of Private Access Modifier
  
class Data {
    
   // private variable
   private String name;
}
public class Main {
   public static void main(String[] main){
       
       // create an object of Data
       Data d = new Data();
       
       // access private variable and field from another class
       d.name = "Kapil";
   }
}


Output:

Main.java:18: error: name has private access in Data
     d.name = "Programiz";
      ^

In the above example, we have declared a private variable named name and a private method named display(). When we run the program, we will get the above error:

Protected Access Modifier

Java




// Java program for showcasing the behaviour
// of Protected Access Modifier
  
class Animal {
    
    // protected method
    protected void display() {
        System.out.println("I am an animal");
    }
}
  
class Dog extends Animal {
    
    public static void main(String[] args) {
  
        // create an object of Dog class
        Dog dog = new Dog();
        
        // access protected method
        dog.display();
    }
}


Output

I am an animal

Public Access Modifier:

Java




// Java program for showcasing the behaviour
// of Public Access Modifier
  
// Animal.java file
// public class
  
class Animal {
    
    // public variable
    public int legCount;
  
    // public method
    public void display() {
        System.out.println("I am an animal.");
        System.out.println("I have " + legCount + " legs.");
    }
}
  
// Main.java
public class Main {
    public static void main( String[] args ) {
        // accessing the public class
        Animal animal = new Animal();
  
        // accessing the public variable
        animal.legCount = 4;
        // accessing the public method
        animal.display();
    }
}


Output

I am an animal.
I have 4 legs.
RELATED ARTICLES

Most Popular

Recent Comments