Java 简明教程

Java - Encapsulation

Java Encapsulation

Encapsulation 是四个基本 OOP concepts 之一。其他三个是 inheritancepolymorphismabstraction

Java 中的封装是一种将数据 ( variables) 和作用于数据 ( methods) 的代码包装在一起作为单个单元的机制。在封装中, class 的变量将对其他类隐藏,并且只能通过它们当前类的的方法访问。因此,它也被称为 data hiding

Achieving Encapsulation in Java

若要在 Java 中实现封装:

  1. 将类的变量声明为私有。

  2. 提供公有设置器和取值器方法,以修改和查看变量值。

Java Encapsulation Example

以下示例演示如何在 Java 中实现封装:

/* File name : EncapTest.java */
public class EncapTest {
   private String name;
   private String idNum;
   private int age;

   public int getAge() {
      return age;
   }

   public String getName() {
      return name;
   }

   public String getIdNum() {
      return idNum;
   }

   public void setAge( int newAge) {
      age = newAge;
   }

   public void setName(String newName) {
      name = newName;
   }

   public void setIdNum( String newId) {
      idNum = newId;
   }
}

公有 setXXX() 和 getXXX() 方法是 EncapTest 类实例变量的访问点。通常,这些方法称为取值器和设置器。因此,要访问变量的任何类都应该通过这些取值器和设置器进行访问。

可以使用以下程序访问 EncapTest 类的变量:

/* File name : RunEncap.java */
public class RunEncap {

   public static void main(String args[]) {
      EncapTest encap = new EncapTest();
      encap.setName("James");
      encap.setAge(20);
      encap.setIdNum("12343ms");

      System.out.print("Name : " + encap.getName() + " Age : " + encap.getAge());
   }
}

public class EncapTest {
   private String name;
   private String idNum;
   private int age;

   public int getAge() {
      return age;
   }

   public String getName() {
      return name;
   }

   public String getIdNum() {
      return idNum;
   }

   public void setAge( int newAge) {
      age = newAge;
   }

   public void setName(String newName) {
      name = newName;
   }

   public void setIdNum( String newId) {
      idNum = newId;
   }
}

Output

Name : James Age : 20

Benefits of Encapsulation

  1. 一个类中的字段可以被设置为仅读或仅写。

  2. 一个类对其字段中所存储的内容拥有完全控制权。

Java Encapsulation: Read-Only Class

一个仅读类只能有 getter 方法去获取属性值,不应有任何 setter 方法。

Example: Creating Read-Only Class

这个例子中,我们定义了一个带有两个 getter 方法的 Person 类:getName() 和 getAge()。这些方法能被用来获取类中声明为私有属性的值。

// Class "Person"
class Person {
  private String name = "Robert";
  private int age = 21;

  // Getter methods
  public String getName() {
    return this.name;
  }

  public int getAge() {
    return this.age;
  }
}

public class Main {
  public static void main(String args[]) {
    // Object to Person class
    Person per = new Person();

    // Getting and printing the values
    System.out.println("Name of the person is: " + per.getName());
    System.out.println("Age of the person is: " + per.getAge());
  }
}
Name of the person is: Robert
Age of the person is: 21

Java Encapsulation: Write-Only Class

一个仅写类只能有 setter 方法去设置属性值,不应有任何 getter 方法。

Example: Creating Write-Only Class

这个例子中,我们定义了一个带有两个 setter 方法的 Person 类:setName() 和 setAge()。这些方法能被用来设置类中声明为私有属性的值。

// Class "Person"
class Person {
  private String name;
  private int age;

  // Setter Methods
  public void setName(String name) {
    this.name = name;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

public class Main {
  public static void main(String args[]) {
    // Object to Person class
    Person per = new Person();

    // Setting the values
    per.setName("Robert");
    per.setAge(21);
  }
}

Java Encapsulation: More Examples

Example 1: Person Class (Fully Encapsulated)

这个例子创建了一个名为 "Person" 的完全封装类。这个类有私有类属性、setter 和 getter 方法。

// Class "Person"
class Person {
  private String name;
  private int age;

  // Setter Methods
  public void setName(String name) {
    this.name = name;
  }
  public void setAge(int age) {
    this.age = age;
  }

  // Getter methods
  public String getName() {
    return this.name;
  }

  public int getAge() {
    return this.age;
  }
}

// The Main class to test encapsulated class "Person"
public class Main {
  public static void main(String args[]) {
    // Objects to Person class
    Person per1 = new Person();
    Person per2 = new Person();

    // Setting the values
    per1.setName("Robert");
    per1.setAge(21);

    per2.setName("Riyan");
    per2.setAge(22);

    // Printing the values
    System.out.println("Person 1: Name : " + per1.getName() + " Age : " + per1.getAge());
    System.out.println("Person 2: Name : " + per2.getName() + " Age : " + per2.getAge());

  }
}
Person 1: Name : Robert Age : 21
Person 2: Name : Riyan Age : 22

Example 2: Employee Class (Fully Encapsulated)

这个例子创建了一个名为 "Employee" 的完全封装类。这个类有私有类属性、setter 和 getter 方法。

// Class "Employee"
class Employee {
  private String emp_name;
  private String emp_id;
  private double net_salary;

  // Constructor
  public Employee(String emp_name, String emp_id, double net_salary) {
    this.emp_name = emp_name;
    this.emp_id = emp_id;
    this.net_salary = net_salary;
  }

  // Getter methods
  public String getEmpName() {
    return emp_name;
  }

  public String getEmpId() {
    return emp_id;
  }

  public double getSalary() {
    return net_salary;
  }

  // Setter methods
  public void setEmpName(String emp_name) {
    this.emp_name = emp_name;
  }

  public void setEmpId(String emp_id) {
    this.emp_id = emp_id;
  }

  public void setSalary(double net_salary) {
    this.net_salary = net_salary;
  }
}

// The Main class to test encapsulated class "Employee"
public class Main {
  public static void main(String args[]) {
    // Objects to Employee class
    // First object - setting values using constructor
    Employee emp = new Employee("Robert", "EMP001", 75450.00);

    // Printing data
    System.out.println("Employee (Intial Values):");
    System.out.println(emp.getEmpId() + " , " + emp.getEmpName() + " , " + emp.getSalary());

    // Updating values using setter methods
    emp.setEmpName("Riyan");
    emp.setEmpId("EMP002");
    emp.setSalary(90500.00);

    // Printing data
    System.out.println("Employee (Updated Values):");
    System.out.println(emp.getEmpId() + " , " + emp.getEmpName() + " , " + emp.getSalary());
  }
}
Employee (Intial Values):
EMP001 , Robert , 75450.0
Employee (Updated Values):
EMP002 , Riyan , 90500.0