Encapsulation in Java
Encapsulation is a concept of protecting data and behavior of an object. It's very close related to another aspect of OOP: abstraction. Encapsulation enables a programmer to implement the desired level of abstraction, to hide information details. These two concepts makes OOP “safer” and easier to use.
Private Sign
In Java, encapsulation is done using classes, interfaces, setters and getters, and access modifiers.
- A class or an interface encapsulated the set of features that are common to all objects of one type.
- Setters and getters to control how variables are accessed and updated in the proper manner .
- Access modifiers to restrict the scope of a class, constructor, variables, methods or other data members.
Java supports the following access modifiers:
- private
- public
- protected
- default
private
private access modifier allows a class to hide its member variables and member functions from another class. Only functions in the same class can access its private members. Even a subclass cannot access private members of the base class.
public
public access modifier allows a class to expose its member variables and member functions to another class. Any public members can be accessed from outside the class.
Let's check our example below.
public class Rectangle {
// member variables are private,
// then we implement setter & getter
private double height;
private double width;
/**
* @return the height
*/
public double getHeight() {
return height;
}
/**
* @param height the height to set
*/
public void setHeight(double height) {
this.height = height;
}
/**
* @return the width
*/
public double getWidth() {
return width;
}
/**
* @param width the width to set
*/
public void setWidth(double width) {
this.width = width;
}
public double getArea() {
return this.height * this.width;
}
public void display() {
System.out.println("Height: " + this.height);
System.out.println("Width: " + this.width);
System.out.println("Area: " + getArea());
}
}
public class RectangleApp {
public static void main(String[] args) {
Rectangle r = new Rectangle();
r.setHeight(2.4);
r.setWidth(4.9);
r.display();
}
}
/*
Output:
------
Height: 2.4
Width: 4.9
Area: 11.76
*/
Class Rectangle
has 2 private members, height & weight. To access height and weight, another class must go through class Rectangle's setter and getter. So code below:
public static void main(String[] args) {
Rectangle r = new Rectangle();
r.height = 2.4;
r.width = 4.9;
r.display();
}
will resulting compilation error:
RectangleApp.java:[5,10] height has private access in Rectangle RectangleApp.java:[6,10] width has private access in Rectangle
The member functions getArea()
and display()
in Class Rectangle can access these variables. In the example, since function display()
is declared public, it can be accessed from main()
using an instance of the Rectangle
class, named r.
protected
protected access modifier allows a subclass to access "non private" member variables and member functions of its base class. This way it helps in implementing inheritance. Please read here for Inheritance in Java.
Let's check example codes below:
public class Rectangle {
// member variables are protected
protected double height;
protected double width;
protected double getArea() {
return this.height * this.width;
}
}
public class Square extends Rectangle {
public String checkSquare() {
if (this.width == this.height) {
return "a square";
}
else {
return "not a square";
}
}
public static void main(String[] args) {
Square s1 = new Square();
s1.height = 10;
s1.width = 12;
System.out.print("s1 is " + s1.checkSquare());
System.out.println (" with area: " + s1.getArea());
Square s2 = new Square();
s2.height = 7;
s2.width = 7;
System.out.print("s2 is " + s2.checkSquare());
System.out.println (" with area: " + s2.getArea());
}
}
/*
Output:
------
s1 is not a square with area: 120.0
s2 is a square with area: 49.0
*/
Since height and width are declared as protected in Rectangle
, Square
as a subclass able to access it directly without the need of helper functions like setter and getter.
default
If we never mention any access modifier above (public, private, and protected), then it becomes default. The members that having this modifier is only accessible by classes (or interfaces) in the same package as the source class. default members would not be visible in the class of another package.
Let's check example below:
package com.dariawan.codes.oop;
public class Polygon {
void draw() {
System.out.println("Drawing Polygon");
}
}
What happen if we have Circle
class but in different packages?
package com.dariawan.codes.shapes;
import com.dariawan.codes.oop.Polygon;
public class Circle extends Polygon {
@Override
public void draw() {
System.out.println("Drawing Circle");
super.draw();
}
}
We will encounter compilation error:
com/dariawan/codes/shapes/Circle.java:[7,5] method does not override or implement a method from a supertype com/dariawan/codes/shapes/Circle.java:[10,14] draw() is not public in com.dariawan.codes.oop.Polygon; cannot be accessed from outside package
draw() method in the Polygon class has no access modifier, which means that it is implicitly assigned the default / package access modifier. Since Circle class is in different package, it'll raise compilation error.
OK, now we know the problem, we need to correct it:
package com.dariawan.codes.oop;
public class Circle extends Polygon {
@Override
public void draw() {
System.out.println("Drawing Circle");
super.draw();
}
}
In Summary
If you cannot remember everything, just remember these summary of Java four access modifiers:
- private - only code in the same class can access this member
- public - any class in any package can access this member
- protected - sub classes in any package can access this member (as well as code in the same class)
- default - only code in the same package can access this member
And here the matrix in table mode from the most restrictive (private) to least restrictive (public):
class | same package | subclass (same package) | subclass (different package) | other class | |
---|---|---|---|---|---|
private | Y | N | N | N | N |
default (no modifier) | Y | Y | Y | N | N |
protected | Y | Y | Y | Y | N |
public | Y | Y | Y | Y | Y |