Java 封装与普通

Java 封装与普通,java,encapsulation,Java,Encapsulation,如果下面的代码将产生相同的结果,为什么要使用封装? 封装的主要好处是能够修改 在不破坏使用我们代码的其他人的代码的情况下实现代码 但是我可以利用这个优势,而不是使用封装,对吗?因为每个对象的场都不同于其他对象的场 // Person.java public class Person { // Plain public String name; // Uses encapsulation private String name2; public void setName(St

如果下面的代码将产生相同的结果,为什么要使用封装?

封装的主要好处是能够修改 在不破坏使用我们代码的其他人的代码的情况下实现代码

但是我可以利用这个优势,而不是使用封装,对吗?因为每个对象的场都不同于其他对象的场

// Person.java
public class Person {
  // Plain
  public String name;

  // Uses encapsulation
  private String name2;
  public void setName(String name2) {
    this.name2 = name2;
  }
  public String getName() {
    return name2;
  }
}

// Main.java
public class Main() {
  public static void main(String[] args) {
    // Plain
    Person person = new Person();
    person.name = "Jordan";
    System.out.println(person.name);

    // Uses encapsulation
    Person person2=new Person();
    person2.setName("Jordan");
    System.out.println(person2.getName());
  }
}
  • 通过提供getter和setter,我们可以获得隐藏实现的好处。e、 g.您可以使用延迟初始化、代理等。
  • 代码变得更易于维护,例如,您可以轻松地在一个位置添加预检查和后检查(或验证)。如果您直接或稍后访问变量,则需要在读取值时添加任何验证或某些默认行为,您必须在多个位置对其进行更改。
  • 通过getter和setter,您可以获得多态性的好处。e、 若你们不想在扩展版本中改变变量的值,或者反之亦然,你们可以简单地抛出异常

  • 从调试的角度来看:

  • 提供在访问或更新变量值时代码行的分隔。(可用于检查参考资料)
  • 有时,我们需要知道变量的值在哪里发生了变化。您可以放置调试指针或记录器来调查它

  • 封装是使类中的字段私有并通过公共方法提供对字段的访问的技术

    public class Person {
    
    private String name;
    private Date dob;
    private transient Integer age;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public Date getDob() {
        return dob;
    }
    
    public void setDob(Date dob) {
        this.dob = dob;
    }
    
    public int getAge() {
        if (age == null) {
            Calendar dob_cal = Calendar.getInstance();
            dob_cal.setTime(dob);
            Calendar today = Calendar.getInstance();
            age = today.get(Calendar.YEAR) - dob_cal.get(Calendar.YEAR);
            if (today.get(Calendar.MONTH) < dob_cal.get(Calendar.MONTH)) {
                age--;
            } else if (today.get(Calendar.MONTH) == dob_cal.get(Calendar.MONTH)
                    && today.get(Calendar.DAY_OF_MONTH) < dob_cal.get(Calendar.DAY_OF_MONTH)) {
                age--;
            }
        }
        return age;
      }
    }
    
    公共类人物{
    私有字符串名称;
    私人约会日期;
    私人短暂整数年龄;
    公共字符串getName(){
    返回名称;
    }
    公共void集合名(字符串名){
    this.name=名称;
    }
    公开日期getDob(){
    返回dob;
    }
    公共无效设置日期(日期日期){
    this.dob=dob;
    }
    公共整数getAge(){
    如果(年龄==null){
    Calendar dob_cal=Calendar.getInstance();
    dob校准设定时间(dob);
    Calendar today=Calendar.getInstance();
    年龄=今天.get(日历年)-dob_cal.get(日历年);
    如果(今天获取(日历月)

    方法
    getAge()
    返回人员年龄,您无需担心如何实现它,也无需在类之外计算年龄。

    使用封装的一种方法是隐藏实现。例如,有时一个getter不是getter。考虑像球体这样的形状,我不一定把体积或表面积存储为变量,因为我可以在任何时候计算它们。我仍然会调用成员函数getVolume和getsurfaceearea。使用我的代码的人不需要知道我是计算还是简单地存储值。通过公开我的变量,我将它们锁定在一个设计决策中,如果我改变我的实现,这个决策将不得不改变(或被打破)。通过隐藏实现,您只需要知道接口(不要与Java的“接口”混淆),它就可以以这种方式保护每个人,并使将来的更改变得更容易


    应该注意的是,有时不使用setter/getter,而暴露变量。即使在Java中,有时不隐藏实例变量也更有意义。

    你的问题很有趣。我会尽力深入地回答你

    封装背后的主要思想是对其他用户隐藏数据及其实现的详细信息。如果我们将一个数据成员设置为私有,那么它只能在同一个类中访问。没有其他类可以直接访问该数据段

    但是我们可以定义一个接口,即公共getter和setter方法来更新来自其他类的数据。这可确保其他人无法访问私有数据,并且只能通过您提供的公共方法访问

    例如,您可能决定只为特定数据成员提供getter方法,而不提供setter方法。这确保没有其他类可以以任何可能的方式更改或更新您的数据成员。只有在需要使用getter方法时,它们才能获得值

    这就是封装也称为数据隐藏的原因

    例子 优势 1) 它为代码提供了灵活性,并使其易于维护。
    我们可以在不影响任何其他外部代码的情况下更改
    getEmpName()
    setEmpName()
    的实现

    2) 我们可以随时使数据成员只读(仅通过定义getter)或仅写(仅通过定义setter)


    3) 其他用户将不知道幕后发生了什么。他们只知道,要更新数据,我们需要调用setter方法,要获取数据,我们需要调用getter方法。

    最大的好处是,当您不需要使用getter和setter深入对象字段时,当您真正隐藏除需要访问的内容之外的所有内容时。person类最好(例如)在构造函数中设置字段,因此setter或getter,以及
    name()
    方法或返回格式化名称的等效方法。事实上,大部分getter和setter都是无用的样板代码。诚然,一小部分对象可能在getter/setter中封装了一些逻辑,而不是基本的东西,但我认为如果您的设计是合理的,这是一个罕见的事件。在对象构造时,从dob计算年龄不是更好吗?除非人的物体在记忆中保存多年,因此最初的计算可能不正确。。还有,在每个getter上反复计算年龄
    public class EncapsulationDemo{
        private int ssn;
        private String empName;
        private int empAge;
    
        //Getter and Setter methods
        public int getEmpSSN(){
            return ssn;
        }
    
        public String getEmpName(){
            return empName;
        }
    
        public int getEmpAge(){
            return empAge;
        }
    
        public void setEmpAge(int newValue){
            empAge = newValue;
        }
    
        public void setEmpName(String newValue){
            empName = newValue;
        }
    
        public void setEmpSSN(int newValue){
            ssn = newValue;
        }
    }
    public class EncapsTest{
        public static void main(String args[]){
             EncapsulationDemo obj = new EncapsulationDemo();
             obj.setEmpName("Mario");
             obj.setEmpAge(32);
             obj.setEmpSSN(112233);
             System.out.println("Employee Name: " + obj.getEmpName());
             System.out.println("Employee SSN: " + obj.getEmpSSN());
             System.out.println("Employee Age: " + obj.getEmpAge());
        } 
    }