There are two parts of a class: the interface and the implementation.
The interface is the exposed functionality of the class. Its public methods and variables are part of the interface.
The implementation is the internal workings of a class. Other classes shouldn't need to know about the implementation of a class.
Encapsulation refers to the practice of hiding the implementation of a class from any users of that class. This allows the class to make assumptions about its internal state.
For example, take this class representing an Angle:
public class Angle {
private double angleInDegrees;
private double angleInRadians;
public static Angle angleFromDegrees(double degrees){
Angle a = new Angle();
a.angleInDegrees = degrees;
a.angleInRadians = Math.PI*degrees/180;
return a;
}
public static Angle angleFromRadians(double radians){
Angle a = new Angle();
a.angleInRadians = radians;
a.angleInDegrees = radians*180/Math.PI;
return a;
}
public double getDegrees(){
return angleInDegrees;
}
public double getRadians(){
return angleInRadians;
}
public void setDegrees(double degrees){
this.angleInDegrees = degrees;
this.angleInRadians = Math.PI*degrees/180;
}
public void setRadians(double radians){
this.angleInRadians = radians;
this.angleInDegrees = radians*180/Math.PI;
}
private Angle(){}
}
This class relies on a basic assumption (or invariant): angleInDegrees and angleInRadians are always in sync. If the class members were public, there would be no guarantees that the two representations of angles are correlated.