Classes and Interface

Rule 1: Minimizing the accessibility of classes and members:

Requirement-
How WELL A COMPONENT IS DESIGNED is marked by how much does it HIDES the internal fields and methods . HIDING data and making it minimum possible visibility ensures DECOUPLING. DECOUPLING ensure better maintainability of component and and it can be modified ,updated without worrying.

How? Encapsulation in java is ensured by the place-of-definition of entity and the access-specifiers.

The classes and interface can have one of two access specifiers – public or package-private or default(when no access specifier mentioned)

Application: Only the EXPORT API class should be made public and rest should be given as narrower scope as possible.

USE CASE: when there is a class which is only accessed by one class then the class should be made private static member of class accessing it to make it un-accessible to other class.

The members of class can have one of four access-modifier- private,package-private,protected and public.

  1. Private-is most restrictive access level.members
    • The member is accessible only from the top-level class where it is declared.
  2. package-private -it is a default access specifier to a member.
    • The member is accessible from any class in the package where it is declared. Technically known as default access, this is the access level you get if no access modifier is specified (except for interface members,which are public by default).
  3. Protected– should rarely be used,be comes part of EXPORT API class if used,need to be maintained.
    1. The member is accessible from sub-classes of the class where it is declared and from any class in the package where it is declared.
  4. Public-most open access specifier to a a member . not recommended except for EXPORT API CLASS.

Thumb Rule: Keep as much restrictive access-modifier as possible.

Exceptions : (to the thumb rule)

  1. The access-specifier for OVERRIDING METHOD must be equal or broader than one in super class.this is necessary to ensure that instance of subclass usable anywhere the instance of super class is usable (Liscov substitution principle). In fact compiler will generate error message when you try to have narrower access-modifier
    • A special case of this rule is that if a class implements an interface, all of the class methods that are in the interface must be declared public in the class
  2. To facilitate, it is ACCEPTABLE to modify access specifier to package-private from private but it is UNACCEPTABLE to change more wider access of a private member.
  3. INTERFACE only be public if used as member of a class.
Note:

For members of public class, a huge increase in accessibility occurs when when we move from package-private to protected. A protected member is PART OF CLASS’S EXPORT API and must to be supported forever.

Coding Tips:
  1. Instance fields of public classes should rarely be public [For explanation use contrast-method] –

If an instance field is NON-FINAL or Reference to mutable object then by making it public -(you loose control over instance field i.e)

  • You give-up the ability to limit the values that can be stored in the field.(since it’s by default final and you made it public)
  • You give-up the ability to enforce invariants involving the field.
  • you give up the ability to take any action when the field is modified.

In Short – Classes with public mutable fields are not generally thread-safe.

It is critical that these fields contain either primitive values or references to immutable objects i.e a field containing a reference to a mutable object has all the disadvantages of a nonfinal field. While the reference cannot be modified, the
referenced object can be modified—with disastrous results.

For the instance fields of public class ensure that, they are immutable or non-public,

  1. The same rule applies to static final fields (with an exception)

You can also expose the public static final fields of a class and these fields should be either primitive or reference to immutable objects,
A field containing reference to mutable object has all the limitations of non-final field.
Exception: Non-Zero array field is mutable, so it is wrong for a class to have a public static final array field, or an accessor that returns such a field. If a class has such a field or accessor, clients will be able to modify the contents of the array.

This is a frequent source of security holes:

// Potential security hole!
public static final thing[]  VALUES={} //seemingly unmodifiable but has a security hole

There are two ways to overcome this:

  1. Use private static field and expose this using non-modifiable list
private static final thing[] PRIVATE_VALUES={};
public static final thing[] VALUES= Collection.nonModifyableList(Arrays.asLsit(PRIVATE_VALUES));
  1. Or, you can use clone of private values and pass it as public static final field.
private static final Thing[] PRIVATE_VALUES = { … };  
public static final Thing[] values() {  return PRIVATE_VALUES.clone();  }  

One of the above option can be choosen based on what datatype better suited for client implementation.

Conclusion :Why make private or more restrictive?
  1. It ensures encapsulation hence decoupling and hence better maintainability
  2. Thread safety Available Choice: Keep the fields final and immutable(no setters,no constructors) or,keep it private.

Published by

Unknown's avatar

sevanand yadav

software engineer working as web developer having specialization in spring MVC with mysql,hibernate

Leave a comment