Java封装概念不明确

Java封装概念不明确,java,encapsulation,Java,Encapsulation,这是一个基本问题,但我仍然不理解封装的概念。我不明白我们怎样才能从其他类更改类的属性 我们试图设置类的公共实例值,我们必须创建该类的对象,然后设置该值。每个对象引用不同的内存 该实例值不会影响任何其他对象 即使我尝试使用静态公共实例值进行更改,我也无法更改类属性值 下面给出了示例 // Employee class public class Employee { public static int empid; public static String empname;

这是一个基本问题,但我仍然不理解封装的概念。我不明白我们怎样才能从其他类更改类的属性 我们试图设置类的公共实例值,我们必须创建该类的对象,然后设置该值。每个对象引用不同的内存 该实例值不会影响任何其他对象

即使我尝试使用静态公共实例值进行更改,我也无法更改类属性值

下面给出了示例

// Employee class
public class Employee {
    public static int empid;
    public static String empname;

    public static void main(String[] args) {
        System.out.println("print employe details:"+empid+" "+empname);
    }

    // EmployeeTest  class
    public class EmployeeTest {

        public static void main(String[] args) {
            Employee e = new Employee();
            e.empid=20;
            e.empname="jerry";
            Employee.empid=10;
            Employee.empname="tom";
        }

    }
}
每次运行
Employee
类时,我都会得到相同的值

打印员工详细信息:0 null


即使我没有遵循封装概念,也无法更改employee类的公共实例值。请帮助我理解我出错的概念。

公共静态
字段与类关联,而不是与对象关联,这违反了对象的封装规则

Employee
带有两个封装字段的类
empid和empname

public class Employee {
    private int empid;
    private String empname;

    public int getEmpid(){
        return this.empid;
    } 
    public void setEmpid(int empid){
        this.empid = empid;
    }
    ...
}

public class EmployeeTest {
      public static void main(String[] args) {
            Employee e = new Employee();
            e.setempId(1);
            Employee e1 = new Employee();
            e1.setempId(2);
      }
}

您似乎分别运行两个不同的类,并假设在运行
EmployeeTest
时对属性所做的更改将反映在
Employee
run中。请注意,更改将反映在同一个JRE实例中。请原谅我误解了你的问题

根据用户输入编辑:。以下是如何访问和更新静态成员值的代码:

class Employee {
    public static int empid;
    public static String empname;

    public static void main(String[] args) {
        System.out.println("print employe details:" + empid + " " + empname);
    }
}

// EmployeeTest class
public class EmployeeTest {

    public static void main(String[] args) {
        Employee e = new Employee();
        e.empid = 20;
        e.empname = "jerry";
        Employee.empid = 10;
        Employee.empname = "tom";
        Employee.main(null);
    }

}

运行Employee类时获得输出“print employe details:0 null”的原因是这些变量未初始化。也就是说,您不会在Employee类中为它们分配任何值

在EmployeeTest类中执行的任何操作都不会影响Employee下次运行时的变量值。把java程序的每一个运行都看作是“干净的板岩”。
在封装方面,您确实不应该使用
static
关键字。如果您要进行封装,请查看此问题的另一个答案,它有一个很好的代码示例供您使用。

当然,一个对象上的更改不会影响另一个对象。假设你有一个班级学生,你学校的所有孩子都是它的对象。如果一个人离开学校,这并不意味着其他所有学生(学生班的对象)也应该离开学校

封装是将类变量设置为私有的概念,这样就没有人可以直接处理来自外部世界的数据成员。但是您提供了public方法,让外部世界以您希望的方式处理您的数据成员。Subhrajyoti Majumder在上面给出了封装的良好编码示例

(静态成员对于类的所有对象都是相同的。例如:static count变量,用于计算学生类对象的数量。(在校学生的数量))

按要求编辑:

例如:

public class student{
    public String name;
    public student() {}
 }
public class student{
    private String name;
    public student() {}
    public String getName(){
      return this.name;
      }
 }
在您的主要功能中,外部世界可以使用您的类属性:

student s = new student();
s.name = "xyz";
假设您不想让外部世界更改对象的name属性。然后,您应该将名称“name”设置为私有,并提供一个只查看名称的公共方法(get)

例如:

public class student{
    public String name;
    public student() {}
 }
public class student{
    private String name;
    public student() {}
    public String getName(){
      return this.name;
      }
 }
现在,在main方法中,只能获取name对象,不能像在第一个示例中那样将其设置为新值

student s = new student();
String sname = s.getName();
如果你尝试:

s.name = "newname";

编译器将不允许您这样做。因为您没有访问私人成员的权限。

是的,这有时会有点让人困惑。让我们一步一步来:首先,你需要理解

  • 什么是封装,为什么使用它?
封装是OOP的四个基本概念之一。封装是将类中的字段设置为私有并通过公共方法提供对字段的访问的技术。如果字段声明为私有,则类外的任何人都无法访问它,从而将字段隐藏在类中。因此,封装也称为数据隐藏


封装可以被描述为一种保护屏障,防止类外定义的其他代码对代码和数据进行随机访问。对数据和代码的访问由接口严格控制

封装的主要好处是能够修改我们实现的代码,而不会破坏使用我们代码的其他人的代码。利用此功能,封装为代码提供了可维护性、灵活性和可扩展性

举个小例子:

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;
   }
}
上述方法称为访问器(也称为getter和setter)。现在你可能会问

  • 为什么要使用访问者? 实际上有很多很好的理由来考虑使用访问器而不是直接公开类的字段。

例如,在其他类>访问的类中考虑<强>字段公共。现在,在获取和设置变量时,您需要添加任何额外的逻辑。这将影响使用API的现有客户端。因此,对这个公共字段的任何更改都需要对引用它的每个类进行更改。相反,使用访问器方法,可以很容易地添加一些逻辑,比如缓存一些数据,然后延迟地初始化它。此外,如果新值与以前的值不同,则可以触发属性更改事件。所有这些都将与使用访问器方法获取值的类无缝连接

有很多教程和解释,关于它们是如何和什么的。谷歌他们

至于你目前的问题:

  • 您有两个不同的类,每个类都有一个主类。这是错误的。他们会的
    Encapsulation means combining data and code together(class). The main purpose of encapsulation is you would have full control on data by using the code.
    
    class Encap{
    
    private int amount;
    
    public void setAmount(int amount)
    {
    this.amount = amount;
    }
    
    Here, you can set the amount using the setAmount method, but value should be more than 100. So, i have the control on it.
    
    public void setAmount(int amount)
    {
    if(amount>100)
    this.amount = amount;
    }
    
    public class Main {
    
      public static void main(String[] args) {
        Owner o1=new Car("SONY","Google Maps");
        o1.activate_Sunroof();
        o1.getNavigationSystem();
        o1.getRadioSytem();
     }
    }  
    //Interface designed for exposing car functionalities that an owner can use.
    public interface Owner {
         void getNavigationSystem();
         void getRadioSytem();
         void activate_Sunroof();
    }
    /*
    Car class protects the code and data access from outside world access by implementing Owner interface(i.e, exposing Cars functionalities) and restricting data access via private access modifier.
    */
    public class Car implements Owner {
                    private String radioSystem;
                    private String gps;
    
                    public Car(String radioSystem, String gps) {
                        super();
                        this.radioSystem = radioSystem;
                        this.gps = gps;
                    }
    
                    public String getRadioSystem() {
                        return radioSystem;
                    }
    
                    public void setRadioSystem(String radioSystem) {
                        this.radioSystem = radioSystem;
                    }
    
                    public String getGps() {
                        return gps;
                    }
    
                    public void setGps(String gps) {
                        this.gps = gps;
                    }
    
                    @Override
                    public void getNavigationSystem() {
                        System.out.println("GPS system " + getGps() + " is in use...");
                    }
    
                    @Override
                    public void getRadioSytem() {
                        System.out.println("Radio system " + getRadioSystem() + " activated");
                    }
    
                    @Override
                    public void activate_Sunroof() {
                        System.out.println("Sunroof activated");
                    }
    }