1

I am trying to test encapsulation.

I have madetwo Objects Department and Employee.

Department get passed a instance of Employee, then to test for encapsulation I follow these rules

1.Display the Employee details

2.Display the department details

3.Change the values in the Employee objec

4.Display the Department details again (The information should not change)

5.Again display the Employee details (The information should be changed here).

This works but am I getting the idea of encapsulation wrong by creating a new instance of employee1????

Or

Should I be setting the values for true encapsulation

employee1.setName("Sam")

This changes the second display() call of Department name to Sam.

//Main
package question1;

public class Test {

    public static void main(String[] args) {
        //Creating a instance of both Employee and Department
        Employee employee1 = new Employee("2726354E", "Bob Ings", 30000 );
        Department mainDepartment = new Department("Main Floor", employee1);

        //Displaying both instances of Employee and Department
        employee1.display();    
        mainDepartment.display();

        System.out.println("");     


        //Changing values in constructor for the instance of Employee we made earlier on 
        employee1 = new Employee("626347B", "Sam O'Conor", 24000);

        mainDepartment.display();

        System.out.println("");     
        System.out.println("");

        employee1.display();

    }

}



//Employee Class
package question1;

public class Employee {
    private String ppsNum;
    private String name;
    private double salary;

    //Parameterized constructor 
    public Employee(String ppsNum, String name, double salary) {
        this.ppsNum = ppsNum;
        this.name = name;
        this.salary = salary;
    }

    //Displaying the instance of the object information in a anesthetically pleasing manner
    public void display() {
        System.out.println("Employee Information");
        seperationLine();
        System.out.println("Name: " + getName());
        seperationLine();
        System.out.println("PPS number: " + getPpsNum());
        seperationLine();
        System.out.println("Salary: " + getSalary() + "0");
        seperationLine();
        System.out.println("\n");


    }}

//Department Class
package question1;

public class Department {
    private String deptName;
    private Employee employee;
    private int officeNumber;

    //Constructor with all three parameters 
    public Department(String deptName, Employee employee, int officeNumber) {

        this.deptName = deptName;
        this.employee = employee;
        this.officeNumber = officeNumber;
    }

    //Constructor with the officeNumber set to 0
    public Department(String deptName, Employee employee) {

        this.deptName = deptName;
        this.employee = employee;
        this.officeNumber = 0;
    }

    //Displaying the instance of the object information in a anesthetically pleasing manner
    public void display() {
        System.out.println("Department");
        Employee.seperationLine();
        System.out.println("Department Name: " + getDeptName());
        Employee.seperationLine();
        System.out.println("Employee: " + employee.toString());
        Employee.seperationLine();
        System.out.println("Office Number: " + getOfficeNumber());

    }

}
Liam
  • 568
  • 2
  • 15

1 Answers1

1

There is no such thing as "testing" encapsulation.

You need not write any code to determine whether your class is properly following the Encapsulation principle. Encapsulation is an Object Oriented Analysis and Design guideline. Not a programming feature.


Good encapsulation means that you are following two steps:

  1. All the related information should be kept together. Ex: Employee should only have Employee information and Department should only have department information. Employee should not be storing which floor a particular department sits. Or Even should not be having a method called seperationLine(). (IMO, seperationLine() method belongs to another Presentor class)
  2. Only the required information should be made public. Rest all should be private or protected. The goal is not to be secretive but to prevent potential problems by external actors modifying information they shouldn't be modifying. Ex: Employee should not be setting department floor.

Just look at the Employee class and set to private all those fields and methods which you think should not be accessible outside. Further, for the information that Department needs from Employee, create a method in the Employee class which the Department can call. That way, Employee is not modifiable by Department but it can access the information it needs.

displayName
  • 13,888
  • 8
  • 60
  • 75
  • Thanks, but what about the getters&setters they can be accessed from `main()`. Does this not break the encapsulation? – Liam Oct 18 '19 at 11:28
  • @Liam: The getters and setters will be accessible to whoever has access to the employee object. That is not what encapsulation enables. The fact that you are using getters and setters instead of directly modifying the Name or Salary value of an employee is how you have maintained the encapsulation. (1/2) – displayName Oct 18 '19 at 12:06
  • @Liam: Another example that makes it easier to understand - Java linked list have a size field. But you don't have a setter for size simply because you do not want to allow anyone to change the size just for kicks. The privacy of setter helps LL ensure that the size field correctly reflects the number of nodes in the LL and with that both conditions of Encapsulation principle are met (Related info together && Only required entities (in this case the getter of size, but not setter) made public). (2/2) – displayName Oct 18 '19 at 12:08
  • @Liam: Wrote this [one](https://stackoverflow.com/a/34070522/1835769) long time back. May be useful. – displayName Oct 18 '19 at 12:09
  • Ok I get it the confusion was the setters I did not understand if you did not want anybody being able to change the values from outside of the class, why they were in in nearly every class. – Liam Oct 18 '19 at 12:19
  • @Liam: Your setter may not be just ‘setting’ a field. It may also be updating something else that depends on the value the setter is supposed to be setting. How would you ensure within your class that whenever the value is being set, the depending value is also being updated? By putting both those actions in the setter and that way completely cutting the chance that someone just sets the value but doesn’t update the dependent value. And all this is valid even if the setter is private and the setter is being called only from within the class. – displayName Oct 18 '19 at 12:32
  • @Liam: BTW, this idea that the object has all required values in the correct state always, is called *[Maintaining the invariant](https://en.wikipedia.org/wiki/Class_invariant).* – displayName Oct 18 '19 at 14:57