Java封装概念不清楚
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19044362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Encapsulation Concept not clear
提问by user2693404
This is basic question but still i don't understand encapsulation concept . I did't understand how can we change the properties of class from other class.because whenever we try to set the public instance value of class we have to create object of that class and then set the value.and every object refer to different memory.so even if we change the instance value this will not impact to any other object.
这是基本问题,但我仍然不理解封装概念。我不明白我们如何从其他类更改类的属性。因为每当我们尝试设置类的公共实例值时,我们都必须创建该类的对象,然后设置该值。每个对象都引用不同的内存.so 即使我们更改实例值,这也不会影响任何其他对象。
Even I try to change using static public instance value also i am not able to change the class property value.
即使我尝试使用静态公共实例值进行更改,我也无法更改类属性值。
Example is given below
示例如下
// 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";
}
}
}
Every time I run Employee
class I am getting same value
每次我Employee
上课时,我都会得到相同的价值
print employe details:0 null
print employe details:0 null
Even though I am not following encapsulation concept and I am not able to change public instance value of employee class.Please help me to understand the concept where i am going wrong.
即使我没有遵循封装概念,也无法更改员工类的公共实例值。请帮助我理解我出错的概念。
回答by Subhrajyoti Majumder
public static
field's are associated with class not with object, it break Object's encapsulation rule.
public static
字段与类相关而不与对象相关联,它破坏了对象的封装规则。
Employee
class with two encapsulated field empid & empname
.
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);
}
}
回答by Juned Ahsan
It seems you are running two different classes separately and assuming the changes done to attributes when you run EmployeeTest
will reflect in Employee
run. Note that changes will reflect in the same JRE instance. Excuse me in case i have misunderstood your problem.
您似乎正在分别运行两个不同的类,并假设您运行时对属性所做的更改EmployeeTest
将反映在Employee
运行中。请注意,更改将反映在同一个 JRE 实例中。对不起,如果我误解了你的问题。
EDIT:As per the user input. Here is the code how you can access and update the static member values:
编辑:根据用户输入。以下是如何访问和更新静态成员值的代码:
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);
}
}
回答by William Gaul
The reason you are getting the output "print employe details:0 null" when running the Employee class is because those variables are not initialized. That is, you do not assign any values to them within the Employee class.
在运行 Employee 类时得到输出“打印员工详细信息:0 null”的原因是这些变量未初始化。也就是说,您不在 Employee 类中为它们分配任何值。
Whatever you do within the EmployeeTest class will not affect the values of the variables in Employee the next time it is run. Consider each run of a Java program a "clean slate".
无论您在 EmployeeTest 类中做什么,都不会影响 Employee 下次运行时变量的值。将 Java 程序的每次运行视为“干净的石板”。
On the point of encapsulation, you really should not be using the static
keyword. If you are going for encapsulation check out the other answer to this question, it has a nice code sample for you to use.
关于封装,您真的不应该使用static
关键字。如果您要进行封装,请查看此问题的其他答案,它有一个不错的代码示例供您使用。
回答by Zeeshan
of course, change on one object will not impact on another object. suppose you have a class studentand all the children at your school are it's objects. if one leaves the school, this doesn't mean, every other student (object of student class) should leave the school too.
当然,一个对象的变化不会影响另一个对象。假设你有一个班级的学生,你学校的所有孩子都是它的对象。如果一个人离开学校,这并不意味着所有其他学生(学生班的对象)也应该离开学校。
Encapsulation is the concept of having your class variables as private, so that no one can directly play with your data members from outer world. but you provide the publicmethod, to let the outer world play with your data member, the way you want them to. the nice coding example of encapsulation is given above by Subhrajyoti Majumder.
封装是将类变量设为private的概念,这样没有人可以直接使用来自外部世界的数据成员。但是您提供了公共方法,让外部世界以您希望的方式与您的数据成员一起玩。上面 Subhrajyoti Majumder 给出了很好的封装编码示例。
(static members are same for all objects of the class. eg: static count variable, to count the number of student class objects. (number of students at school)).
(静态成员对于类的所有对象都是相同的。例如:静态计数变量,用于计算学生类对象的数量。(学校的学生数量))。
Edit as you asked for:
按照您的要求进行编辑:
Example:
例子:
public class student{
public String name;
public student() {}
}
and in your main function, outer world can play with your class attributes as:
在您的主要功能中,外部世界可以将您的类属性用作:
student s = new student();
s.name = "xyz";
let's suppose, you don't want to let the outer world change your name attribute of object. then you should make name 'name' as private, and provide a public method to only view the name (get).
让我们假设,您不想让外部世界更改对象的名称属性。那么您应该将名称'name'设为私有,并提供一个公共方法来仅查看名称(get)。
Example:
例子:
public class student{
private String name;
public student() {}
public String getName(){
return this.name;
}
}
and now in your main method, you can only get the name object, and can't set it to new value, like you could do in first example.
现在在您的 main 方法中,您只能获取 name 对象,而不能将其设置为新值,就像您在第一个示例中所做的那样。
student s = new student();
String sname = s.getName();
and if you try:
如果你尝试:
s.name = "newname";
compiler will not allow you that. since you don't have permission to access the private members.
编译器不会允许你这样做。因为您无权访问私有成员。
回答by user2339071
Yeah, this can be a little confusing sometimes. Let's go step by step: First, you need to understand
是的,这有时会让人有点困惑。让我们一步一步来:首先,您需要了解
- What is encapsulation and why is it used.?
- 什么是封装,为什么要使用它。?
Encapsulation is one of the four fundamental OOP concepts.Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods.If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.
封装是四个一个基本的OOP概念.Encapsulation是一类私人制作领域,并通过公共方式提供接入领域的技术。如果一个字段被声明为私有,类外的任何人都无法访问它,从而隐藏了类内的字段。因此,封装也称为数据隐藏。
Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other codedefined outside the class. Access to the data and code is tightly controlled by an interface.
封装可以被描述为一种保护屏障,防止代码和数据被类外定义的其他代码随机访问。对数据和代码的访问由接口严格控制。
The main benefit of encapsulation is the ability to modify our implemented code without breaking the codeof others who use our code. With this feature Encapsulation gives maintainability, flexibility and extensibilityto our code.
封装的主要好处是能够在不破坏使用我们代码的其他人的代码的情况下修改我们实现的代码。有了这个特性,封装为我们的代码提供了可维护性、灵活性和可扩展性。
Take a small example:
举个小例子:
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;
}
}
The above methods are called Accessors(aka getters and setters). Now you might ask,
上述方法称为访问器(又名 getter 和 setter)。现在你可能会问,
- Why should you use accessors..?There are actually many good reasons to consider using accessors rather than directly exposing fields of a class.Getter and Setters make APIs more stable.
- 为什么要使用访问器..?实际上有很多很好的理由可以考虑使用访问器而不是直接暴露类的字段。Getter 和 Setter 使 API 更加稳定。
For instance, consider a field public in a class which is accessed by other classes. Now later on, you want to add any extra logic while getting and setting the variable. This will impact the existing client that uses the API. So any changes to this public field will require change to each class that refers it. On the contrary, with accessor methods, one can easily add some logic like cache some data, lazily initialize it later. Moreover, one can fire a property changed event if the new value is different from the previous value. All this will be seamless to the class that gets value using accessor method.
例如,考虑一个被其他类访问的类中的公共字段。现在,您想在获取和设置变量时添加任何额外的逻辑。这将影响使用 API 的现有客户端。因此,对该公共字段的任何更改都需要对引用它的每个类进行更改。相反,使用访问器方法,可以轻松添加一些逻辑,例如缓存某些数据,稍后对其进行延迟初始化。此外,如果新值与先前值不同,则可以触发属性更改事件。所有这些对于使用访问器方法获取值的类都是无缝的。
There are so many tutorials and explanations as to how and what are they. Google them.
关于它们是什么以及它们是什么,有很多教程和解释。谷歌他们。
As for your, current problem:
至于你目前的问题:
- You have two different classes, each with a main. That is wrong. They will have different properties.
- Code change suggested by @Subhrajyoti Majumder is the correct one. Check the answer for solving the problem.
- 你有两个不同的类,每个类都有一个 main。那是错的。它们将具有不同的属性。
- @Subhrajyoti Majumder 建议的代码更改是正确的。检查解决问题的答案。
In the meantime, read up on
在此期间,请继续阅读
for a better understanding of the concepts. Hope it helps. :)
为了更好地理解这些概念。希望能帮助到你。:)
回答by Lefteris Laskaridis
The concept of encapsulation is a designtechnique that relates with information hiding. The underlying principle is to provide protected access to the class attributes, through a well designed interface. The purpose of encapsulation is to enforce the invariants of the class.
封装的概念是一种与信息隐藏相关的设计技术。基本原则是通过精心设计的接口提供对类属性的受保护访问。封装的目的是强制执行类的不变量。
To follow on your example consider the interface of this class:
要遵循您的示例,请考虑此类的接口:
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;
}
}
Note that by declaring the attributes as private this class restricts clients from directly accessing the state of employee object instances. The only way for clients to access them is via the getName() method. This means that those attributes are encapsulated by the class. Also note that by declaring the attributes as final and initializing them in the constructor we create an effectively immutable class, that is one whose state cannot be modified after construction.
请注意,通过将属性声明为私有,此类限制客户端直接访问员工对象实例的状态。客户端访问它们的唯一方法是通过 getName() 方法。这意味着这些属性被类封装。另请注意,通过将属性声明为 final 并在构造函数中初始化它们,我们创建了一个有效的不可变类,该类在构造后无法修改其状态。
An alternative implementation would be the following:
另一种实现如下:
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;
}
}
In this example the object is not immutable but its state is encapsulated since access to it takes place only through accessors and modifiers. Note here how encapsulation can help you protect the invariants of the object state. By constraining modifications through a method you gain a better control of how the object state is modified, adding validations to make sure that any modifications are consistent with the specification of the class.
在这个例子中,对象不是不可变的,但它的状态是封装的,因为只有通过访问器和修饰符才能访问它。请注意封装如何帮助您保护对象状态的不变量。通过通过方法约束修改,您可以更好地控制对象状态的修改方式,添加验证以确保任何修改都与类的规范一致。
回答by Satheesh Guduri
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;
}
回答by n ramesh
encapsulation =VARIABLES(let private a,b,c)+ METHODS(setA&getA,setB&getB....) we can encapsulate by using the private modifier. let consider your created one public variable and one private variable in your class... in case if you have to give those variables to another class for read-only(only they can see and use not able to modify) there is no possibility with public variables or methods,but we can able to do that in private by providing get method. so Your class private variables or methods are under your control. but IN public there is no chance....i think you can understood.
encapsulation =VARIABLES(let private a,b,c)+ METHODS(setA&getA,setB&getB....) 我们可以使用 private 修饰符进行封装。让我们考虑一下您在类中创建的一个公共变量和一个私有变量...如果您必须将这些变量提供给另一个类以进行只读(只有他们可以看到和使用不能修改),则不可能公共变量或方法,但我们可以通过提供 get 方法来私下做到这一点。所以你的类私有变量或方法在你的控制之下。但在公共场合没有机会......我想你可以理解。
回答by Abderrahmen
The encapsulation is an OOP concept. The class is considered like a capsule that contains data + behavior. The data should be private and should be accessed only using public methods called getters and setters. You may check this encapsulationtutorial for more informations about this concept.
封装是一个面向对象的概念。该类被视为包含数据 + 行为的胶囊。数据应该是私有的,并且只能使用称为 getter 和 setter 的公共方法访问。您可以查看此封装教程以获取有关此概念的更多信息。
回答by Rohit Gaikwad
Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other code defined outside the class.Access to the data and code is tightly controlled by an interface.
封装可以被描述为一种保护屏障,防止代码和数据被类外定义的其他代码随机访问。对数据和代码的访问由接口严格控制。
Encapsulation in Java is the technique of making the fields in a class private and providing access to the fields via public methods.
Java 中的封装是将类中的字段设为私有并通过公共方法提供对字段的访问的技术。
If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.
如果一个字段被声明为私有,类外的任何人都无法访问它,从而隐藏了类内的字段。因此,封装也称为数据隐藏。
Real-time example: cars and owners.All the functionsof cars are encapsulated with the owners. Hence, No one else can access it..
实时示例:汽车和车主。汽车的所有功能都与车主一起封装。因此,没有其他人可以访问它..
The below is the code for this example.
下面是这个例子的代码。
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");
}
}