Java Encapsulation Concept不清楚

这是基本问题,但我仍然不理解封装概念。 我不明白如何从其他类更改类的属性。因为每当我们尝试设置类的公共实例值时,我们必须创建该类的对象然后设置值。每个对象引用不同的内存即使我们更改实例值,这也不会影响任何其他对象。

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

实例如下

// 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类时,我都得到相同的值

print employe details:0 null

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

是的,有时这可能有点令人困惑。 让我们一步一步:首先,你需要了解

  • 什么是封装,为什么使用它。

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

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

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

举一个小例子:

 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; } } 

上述方法称为Accessors(又名getter和setter)。 现在你可能会问,

  • 你为什么要使用访问器..? 实际上有很多理由考虑使用访问器而不是直接暴露类的字段.Getter和Setters使API更稳定。

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

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

至于你当前的问题:

  1. 你有两个不同的类,每个类都有一个main。 那是错的。 他们将拥有不同的属性。
  2. @Subhrajyoti Majumder建议的代码更改是正确的。 检查解决问题的答案。

在此期间,请继续阅读

  • 封装
  • 访问器

为了更好地理解这些概念。 希望能帮助到你。 🙂

您似乎分别运行两个不同的类,并假设在运行EmployeeTest时对属性所做的更改将反映在Employee运行中。 请注意,更改将反映在同一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); } } 

public static字段与不与对象关联的类关联,它打破了对象的封装规则。

具有两个封装字段empid & empname Employee类。

 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); } } 

有关更好地理解封装的文档

封装的概念是一种与信息隐藏相关的设计技术。 基本原则是通过精心设计的界面提供对类属性的受保护访问。 封装的目的是强制类的不变量。

要继续您的示例,请考虑此类的接口:

 class Employee private final String firstName; private final String lastName; public Employee(final firstName, final lastName) { this.firstName = firstName; this.lastName = lastName; } public String getName() { return firstName + " " + lastName; } } 

请注意,通过将属性声明为私有,此类限制客户端直接访问员工对象实例的状态。 客户端访问它们的唯一方法是通过getName()方法。 这意味着这些属性由类封装。 还要注意,通过将属性声明为final并在构造函数中初始化它们,我们创建了一个有效不可变的类,即在构造之后不能修改其状态的类。

另一种实现方式如下:

 class Employee private String firstName; private String lastName; public Employee(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } public String getName() { return firstName + " " + lastName; } public String setName(String firstName, String lastName) { if (firstName == null) { throw new IllegalArgumentException("First name cannot be null"); } if (lastName == null) { throw new IllegalArgumentException("Last name cannot be null"); } this.firstName = firstName; this.lastName = lastName; } } 

在此示例中,对象不是不可变的,但其状态是封装的,因为只有通过访问器和修饰符才能访问它。 请注意封装如何帮助您保护对象状态的不变量。 通过方法约束修改,您可以更好地控制对象状态的修改方式,添加validation以确保任何修改与类的规范一致。

 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; } 

encapsulation = VARIABLES(let private a,b,c)+ METHODS(setA&getA,setB&getB ….)我们可以使用private修饰符进行封装。 让我们考虑你的类中创建的一个公共变量和一个私有变量…如果你必须将这些变量提供给另一个只读类(只有它们可以看到并且无法修改),就不可能公共变量或方法,但我们可以通过提供get方法私下完成。 所以你的类私有变量或方法在你的控制之下。 但在公共场合没有机会……我想你可以理解。

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

Java中的封装是一种将类中的字段设为私有并通过公共方法提供对字段的访问的技术。

如果某个字段被声明为私有,则该类之外的任何人都无法访问该字段,从而将该字段隐藏在该类中。 因此,封装也称为数据隐藏

实时示例: 汽车和车主。 汽车的所有function都由业主封装。 因此,没有其他人可以访问它..

以下是此示例的代码。

 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(ie, 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"); } } 

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

封装是将类变量设置为私有的概念,因此没有人可以直接使用来自外部世界的数据成员。 但是你提供了公共方法,让外部世界以你想要的方式与你的数据成员一起玩。 封面的好编码例子由Subhrajyoti Majumder给出。

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

根据您的要求进行编辑:

例:

 public class student{ public String name; public student() {} } 

在你的主要function中,外部世界可以使用你的类属性:

 student s = new student(); s.name = "xyz"; 

让我们假设,您不希望让外部世界更改对象的名称属性。 那么你应该将名称’name’设为private,并提供一个只查看名称(get)的公共方法。

例:

 public class student{ private String name; public student() {} public String getName(){ return this.name; } } 

现在在你的main方法中,你只能得到名称对象,而不能像第一个例子中那样将它设置为新值。

 student s = new student(); String sname = s.getName(); 

如果你尝试:

 s.name = "newname"; 

编译器不允许你这样做。 因为您无权访问私人会员。

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

无论您在EmployeeTest类中执行什么操作,都不会在下次运行时影响Employee中的变量值。 将每个Java程序运行视为“干净的平板”。

在封装方面,你真的不应该使用static关键字。 如果您要进行封装,请查看此问题的其他答案,它有一个很好的代码示例供您使用。

封装是OOP概念。 该类被视为包含数据+行为的包。 数据应该是私有的,只能使用名为getters和setter的公共方法访问。 您可以查看此封装教程以获取有关此概念的更多信息。

封装是将方法和变量包装在一起作为一个单元的机制。 例如胶囊,即混合了几种药物。

类的变量将从其他类中隐藏,因为它将被声明为私有,并且只能通过其当前类的方法访问

在Java中实现封装 – *将类的变量声明为私有。 *提供公共setter和getter方法来修改和查看变量值。 * Java Bean类是完全封装类的示例。

你的意思是说empid的值应该是10而empname tom而不是0和null,如果是,那么 – :

1)变量的内存在运行时分配,并在程序终止后也解除分配。

2)因此,如果你认为如果你给10分一次它应该总是10,那就不是这样,因为empid只是对存储“10”的存储器的引用。

3)因此,通过解除分配,我的意思是在程序终止之后,empid不再指向存储10的存储区域

4)每当执行一个新程序时,empid现在指向其他内存区域,并且在静态变量的情况下,根据相应的数据类型为该内存分配默认值。 因此总是0和null。