Encapsulation of data in class. Access Control in Java. Modifiers private, public, protected

Encapsulation of data in class. Access Control in Java. Modifiers private, public, protected

1. What is the encapsulation in a class?

Encapsulation in a class means granting appropriate access to class members using special access modifiers: private, protected, public. Access can be set as the data, and to the methods of a class.

 

2. What are the availability categories of class data members in the Java language?

There are 4 accessibility categories in Java:

  • derived classes (subclasses) in one package;
  • classes in the same package that are not derived;
  • derived classes (subclasses) in different packages;
  • classes that are in different packages and are not derived (not subclasses).

 

3. What are the advantages of encapsulation mechanism in the class?

Encapsulating class data provides the following advantages:

  • if the class data is hidden, then it protects against abuse or accidental access to it. Data access is provided through specially developed class methods;
  • if the data (methods) of the class is hidden, then they represent a kind of “black box”. Interaction with data is provided through the appropriate class methods;
  • flexibility in providing access to different types of class data using appropriate modifiers;
  • in access methods for hidden class data, you can do the appropriate checks for correctness.

 

4. What access modifiers apply to data from class methods?

To control access to data from class methods, Java uses the following access modifiers:

  • private. In this case, the data (methods) are hidden. Only class methods have access to such data. From the instance (object) of the class, private-elements are inaccessible;
  • public. If a class member is declared with the public access modifier, then this class member is accessible from any code in the given package and outside the package (for all methods of all classes);
  • protected. This modifier is used when it is necessary that the class element is accessible outside the current package, but only to classes directly derived (inherited) from this class.

Also class members can be declared without an access modifier.

 

5. What is the general form of declaring an element of a class with a given access modifier?

The access modifier to a specific data member or method is set before it is declared.

The general form of a class in which one member of the class data and one method are declared are as follows.

class ClassName {
    // declaration of class data member
    access_modifier type variable;

    // method declaration in class
    access_modifier return_type MethodName(parameters) {
        // the method body
        // ...
    }
}

here

  • ClassName – class name being declared;
  • access_modifier – one of the access modifiers is private, public, protected;
  • type – type of data member of class with variable name;
  • variable – data member of a class that is declared with type type;
  • return_type – a type that returns a class method named MethodName();
  • parameters –the parameters that the MethodName() method receives.
6. Access to class members which declared with private access modifier. Example

The class elements declared with the private access modifier are hidden. Only methods of this class have access to them. Of all other parts of the program code, there is no access to private members of the class.

This way of hiding data in a class is effective in cases where it is necessary:

  • hide the details of the organization of data structures and the implementation of this class;
  • avoid possible accidental changes to the data in the class instance;
  • provide easy access to data in the class using specially developed methods. Here we mean the development of methods in the class that provide read/write data of a class. These methods may include appropriate validation checks when the data in the class changes;
  • to avoid possible abuses of data in the class which can lead to subtle errors in the program.

Example. An example of accessing a private-class variable using access methods is shown. A class that implements the day of the week is declared. The class declares a hidden member of the class data named value. To access the value in the class are used:

  • constructor DayWeek(), which initializes the value value = 1. Constructor declared without modifier. This means that within a package it has a public access type;
  • Get() method that returns value. Since the method is declared in the DayWeek class, the method body has access to the value variable;
  • Set() method, which sets the new value. The method is also declared in the class, therefore it has access to value. The method checks for the correctness of the value in the range 1..7. If you specify a different value, the value will not change;
  • GetName() method, which returns the name of the day of the week depending on the value.

The implementation of the DayWeek class is as follows

// class that implements the day of the week
class DayWeek {
    private int value; // hidden class variable

    // class constructor, initializes the value variable
    DayWeek() {
        value = 1; // default is "Monday"
    }

    // access methods
    // method that returns data in class
    public int Get() {
        return value;
    }

    // method that sets a new day of the week
    public void Set(int _value) {
        // the method checks for correctness of the _value value
        if ((_value>=1)&&(_value<=7))
            value = _value;
    }

    // additional method
    // returns the name of the day of the week to which value corresponds
    public String GetName() {
        String day = "Monday";
        switch (value) {
            case 2: day = "Tuesday"; break;
            case 3: day = "Wednesday"; break;
            case 4: day = "Thursday"; break;
            case 5: day = "Friday"; break;
            case 6: day = "Saturday"; break;
            case 7: day = "Sunday"; break;
        }
        return day;
    }
}

You can use this class in another code (method), for example, as follows.

public class HiddenData {
    public static void main(String[] args) {
        // access to the private member of the class
        DayWeek dw = new DayWeek();
        int Day;
        String strDay;

        Day = dw.Get(); // Day = 1
        strDay = dw.GetName(); // strDay = "Monday"

        System.out.println("Day = " + Day);
        System.out.println("strDay = " + strDay);

        // set the new day
        dw.Set(3);

        // check
        Day = dw.Get(); // Day = 3
        strDay = dw.GetName(); // strDay = "Wednesday"

        System.out.println("Day = " + Day);
        System.out.println("strDay = " + strDay);
    }
}

The result of the above program

Day = 1
strDay = Monday
Day = 3
strDay = Wednesday

 

7. Access to class elements that are declared with the public access modifier. Examples

Class elements that are declared with the public access modifier are accessed from any program code in the package in which the class is declared.

If you need to have access to public elements of a class from other packages, then this class must be declared with the public modifier. More details about the features of access to public classes from other packages are described in the topic:

 

7.1. An example of accessing a public element of a class within a package

Class A is set with the data member value, which is declared with the public modifier. Below are three possible ways to access the public-member value:

  • from the current class A;
  • from class B, which is declared in this package;
  • from class C, which is declared in this package, and is derived from class A.

 

// some class
class A {
    public int value; // variable declared with the public modifier

    // access from the method of current class
    void methodA() {
        value = 5;
    }
}

class B {
    // access from another class method of this package
    void methodB() {
        A objA = new A();
        objA.value = 10;
    }
}

// class C inherits class A
class C extends A {
    // access from a derived class method
    void methodC() {
        value = 30;
    }
}

 

7.2. An example of accessing a public element of a class from another package

To have access to a public element of a class from another package, this class can also be declared as public.

Let the package Package1 define a class named DemoPackage1. The public variable value is declared in the class.

// public access modifier, Package1 package
package Package1;

// package Package1
// public-class DemoPackage1
public class DemoPackage1 {
    public int value; // This variable is available outside the package.

    public static void main(String[] args) {

    }
}

Then, access from another Package2 package to the value variable can be:

  • using an instance (object) of the class Package1.DemoPackage1;
  • using a class that is derived from the class Package1.DemoPackage1.
// package Package2
package Package2;

// include the class DemoPackage1 from Package1
import Package1.DemoPackage1;

// some class in Package2
public class DemoPackage2 {
    public static void main(String[] args) {
        // creating an instance of the class DemoPackage1,
        // which is placed in package1 is allowed
        Package1.DemoPackage1 dp1 = new Package1.DemoPackage1();

        // access to a public class variable from another package that is declared as public
        dp1.value = 30;
    }
}

// class that inherits (extends) the class DemoPackage1 from package Package1
class DemoPackage3 extends DemoPackage1 {
    // method that has access to Package1.DemoPackage1.value
    void IncValue(int _delta) {
        value = value + _delta; // increase value by delta
    }
}

It should be noted if the directive is placed in the package Package2

import Package1.DemoPackage1;

then the DemoPackage1 class from Package1 can be accessed in either of two ways:

  • based on the package name: Package1.DemoPackage1;
  • without using the package name before the class name: DemoPackage1.

 

8. Access to class members that are declared with the protected access modifier. Examples

Consider two cases of access to a protected-element of a class:

  • within the package in which the class with this protected-element is declared (in the current package);
  • from another package.

If in some package the class element is declared with the keyword protected, then:

  • in the current package, this element is visible from any code (as well as a public element);
  • in another package, this element is visible only in derived classes.

Let us prove it by examples.

 

8.1. An example of access to a protected member of class data within a package

Class A is defined, in which the protected member of the value is declared. From this package, the value class element can be accessed in the following ways:

  • from current class A;
  • from class B, which is declared in this package;
  • from class C, which is declared in this package, and is derived from class A.
// access modifier protected
package Package1;

// some class
class A {
    protected int value; // variable declared with the protected modifier

    // access from the method of current class
    void methodA() {
        value = 5;
    }
}

class B {
    // access from another class method of this package
    void methodB() {
        A objA = new A();
        objA.value = 10;
    }
}

// class C inherits class A
class C extends A {
    // access from a derived class method
    void methodC() {
        value = 30;
    }
}

From the above code we can draw the following conclusion:

  • within a package, access to protected-elements of a class is the same as to public-elements of a class.

 

8.2. An example of access to a protected member of class data from another package

In order for a protected-element of a class to be available outside of this package, this class must be declared with the public modifier.

In order to access a protected-element of a class from the classes of other packages, these classes must be derived from this class.

Consider this by example.

Let a package named Package1 be given. This package implements the class DemoPackage1, in which the protected variable value is declared.

// access modifier protected,
package Package1;

// public-class DemoPackage1
public class DemoPackage1 {
     // outside the package, this variable is only available in derived classes
    protected int value;

    public static void main(String[] args) {

    }
}

The following code demonstrates access from another package Package2 to the value protected-variable of the class DemoPackage1 (package Package1).

package Package2;

// include the class DemoPackage1 from package Package1
import Package1.DemoPackage1;

// some class in package Package2
public class DemoPackage2 {
    public static void main(String[] args) {
        // creating an instance of the class DemoPackage1,
        // which is placed in package1 - it is allowed
        Package1.DemoPackage1 dp1 = new Package1.DemoPackage1();

        // access to protected class variable from another package
        // dp1.value = 30; - access FORBIDDEN, error
    }
}

// class that inherits (extends) the class DemoPackage1 from package Package1
// this class has access to the protected variable value
class DemoPackage3 extends DemoPackage1 {
    // method that has access to Package1.DemoPackage1.value
    void IncValue(int _delta) {
        value = value + _delta; // access is allowed
    }
}

If you remove the comment from the line

dp1.value = 30;

the compiler will generate an error

The field DemoPackage1.value is not visible

 

9. Features access to class elements in the absence of an access modifier. Examples

When declaring a class member the access modifier to the class members may be missing. In this case, access to a member of a class have:

  • methods of this class;
  • methods of the derived subclass that is declared in this package itself;
  • methods of any class that is located in this package itself.

Access from other packages to class members that do not have an access modifier is prohibited.

Example 1. The example demonstrates access to the value variable of class A from methods of other classes. The variable value of class A is declared without an access modifier.

// no access modifier
package Package1;

class A {
    int value; // variable declared without access modifier

    // access from the current class method
    void method() {
        value = 5; // access is allowed
    }
}

class B {
    // access from another class method of this package
    void method() {
        A obj = new A();// instance of class A
        obj.value = 10; // access is allowed
    }
}

class C extends A {
    // access from a derived class method
    void method() {
        value = 30; // access is allowed
    }
}

Example 2. Demonstration of denying access from another package to the value variable of the class DemoPackage1, which is declared without an access modifier.

Two packages are specified with the names Package1 and Package2. Package1 package declares a public class named DemoPackage1. In this class, the value variable with no access modifier is declared.

Package1 text is as follows:

// Package Package1
// class DemoPackage1
public class DemoPackage1 {
    int value; // This variable is only available in this package.

    public static void main(String[] args) {

    }
}

In another package, Package2 declares the class DemoPackage2 and the import directive, which includes Package1.

// Package2
package Package2;

// include the class DemoPackage1 from package Package1.
import Package1.DemoPackage1;

// some class in package2
public class DemoPackage2 {
    public static void main(String[] args) {
        // creating an instance of the class DemoPackage1,
        // which is placed in package1 - it is allowed
        Package1.DemoPackage1 dp1 = new Package1.DemoPackage1();

        // unable to access a variable in another package
        // which is declared without modifier
        // dp1.value = 10; - error, access to the variable dp1.value is FORBIDDEN!
    }
}

As you can see from an example, attempt to cause a line

dp1.value = 10;

from Package2 will cause a compiler error with the following message

The field DemoPackage1.value is not visible

This means that the value field of the class DemoPackage1 is invisible.

 

10. What type of access do class members have by default?

Before declaring a variable, instance, or method in a class, it is not necessary to specify an access modifier. If the access modifier is missing before declaring members of the class, the default access is assumed. Class members in Java are set to public access by default.

 

11. Is it possible to declare a class constructor with private access modifier?

Yes, it is. Such a constructor will never be called outside the class, that is, from an instance (object) of the class. But such a constructor can be used in methods that are declared in the class itself when creating instances of this class.

For example. Let a class named CData be given. The class declares:

  • the constructor without parameters with the access modifier public;
  • private constructor with one parameter. This constructor will be used in the UseCData() method, which is declared in the same class;
  • the CData() method, which uses the hidden CData() constructor with one parameter.

The text of the declaration and use of the class is:

// class that contains hidden constructor
class CData {
    int d; // data member d has public access by default

    // public constructor, visible outside the class
    CData() {
        d = 0;
    }

    // hidden constructor visible only within the class
    private CData(int _d) {
        d = _d;
    }

    // a method that uses a private constructor
    public void UseCData(int _d)
    {
        CData DD = new CData(_d); // use private class constructor
        System.out.println("DD = "+DD.d);
    }
}

public class TestClass {
    public static void main(String[] args) {
        // create an instance of class CData
        CData D1 = new CData(); // invoke public constructor without parameter

        // It is forbidden to invoke the private constructor of the CData class.
        //CData D2 = new CData(2);

        // access to data member d
        D1.d = 30;
        System.out.println("D1.d = " + D1.d);

        D1.UseCData(55); // display DD=55
    }
}

As can be seen from the class declaration, in the UseCData() method, a hidden constructor with one parameter will be called.

...
CData DD = new CData(_d); // use the private class constructor
...

As a result of executing the above code, the screen will display:

D1.d = 30
DD = 55