I'm having a bit of trouble understanding encapsulation in Java. What I know is that encapsulation allows for information hiding (using private variables) from anywhere else in the program. But, could anyone show me how creating a class with public data fields could cause problems? I'm not understanding how the data is hidden if the classes have getter and setter methods provided.
public class Student{
private int id;
private String name;
private int grade;
public Student(){
}
public Student(int id; String name, int grade){
this.id = id;
this.name = name;
this.grade = grade;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
//more code
}
Here's an example where a public field can make its class completely unreliable. An alternative private version can guarantee that its information is always valid, and is untouchable by undesirable actors.
Public field class (insecure):
class VeryImportantCounterPublic {
public int currentCount;
public VeryImportantCounterPublic(int initial_count) {
currentCount = initial_count;
}
public void incrementCount() {
currentCount++;
}
public int getCurrentCount() {
return currentCount;
}
}
Private field class (secure):
class VeryImportantCounterPrivate {
private int currentCount;
public VeryImportantCounterPrivate(int initial_count) {
currentCount = initial_count;
}
public void incrementCount() {
currentCount++;
}
public int getCurrentCount() {
return currentCount;
}
}
Main:
public class CounterTest {
public static final void main(String[] ignored) {
VeryImportantCounterPublic counter = new VeryImportantCounterPublic(3);
counter.incrementCount();
counter.incrementCount();
counter.incrementCount();
//Should not be able to do this!!
//But it's a public field, so you can :(
counter.currentCount = -203847382;
System.out.println("[PUBLIC] Current count is " + counter.getCurrentCount());
VeryImportantCounterPrivate counter2 = new VeryImportantCounterPrivate(3);
counter2.incrementCount();
counter2.incrementCount();
counter2.incrementCount();
//Can't do this. Compiler error:
//counter2.currentCount = -203847382;
System.out.println("[PRIVATE] Current count is " + counter2.getCurrentCount());
}
}
Output:
[PUBLIC] Current count is -203847382
[PRIVATE] Current count is 6
Full source:
public class CounterTest {
public static final void main(String[] ignored) {
VeryImportantCounterPublic counter = new VeryImportantCounterPublic(3);
counter.incrementCount();
counter.incrementCount();
counter.incrementCount();
counter.currentCount = -203847382;
System.out.println("[PUBLIC] Current count is " + counter.getCurrentCount());
VeryImportantCounterPrivate counter2 = new VeryImportantCounterPrivate(3);
counter2.incrementCount();
counter2.incrementCount();
counter2.incrementCount();
//Can't do this. Compiler error:
//counter2.currentCount = -203847382;
System.out.println("[PRIVATE] Current count is " + counter2.getCurrentCount());
}
}
class VeryImportantCounterPublic {
public int currentCount;
public VeryImportantCounterPublic(int initial_count) {
currentCount = initial_count;
}
public void incrementCount() {
currentCount++;
}
public int getCurrentCount() {
return currentCount;
}
}
class VeryImportantCounterPrivate {
private int currentCount;
public VeryImportantCounterPrivate(int initial_count) {
currentCount = initial_count;
}
public void incrementCount() {
currentCount++;
}
public int getCurrentCount() {
return currentCount;
}
}