对象是否封装数据,以便即使是同一类的其他实例也无法访问数据?

时间:2022-09-02 09:36:11

In Java,

Do objects encapsulate data so that not even other instances of the same class can access the data? Only when the keyword "private" is used? What are "accessor methods" in Java - methods like getName()?

对象是否封装数据,以便即使是同一类的其他实例也无法访问数据?只有在使用关键字“private”时?什么是Java中的“访问器方法” - 像getName()这样的方法?

Thanks

7 个解决方案

#1


I don't tend to think of it in terms of one object having access to another, but rather what code has access to what data within an object.

我不倾向于用一个访问另一个对象的对象来考虑它,而是用什么代码可以访问对象中的哪些数据。

In Java (and C#, btw) code within a class has access to the private members of any object of the same class. Then you've got package/assembly access and public access.

在Java(和C#,btw)中,类中的代码可以访问同一类的任何对象的私有成员。然后你就有了包/程序集访问权限和公共访问权限。

The tricky one is protected access, which is sort of access to code in subclasses - but it depends on the target object: you're only allowed to access protected members of an object if it's an instance of the same type as the location of the code, or some subclass - even if it's being exposed by a parent class. So for instance, suppose you had:

棘手的是受保护的访问,它是对子类中代码的访问 - 但它取决于目标对象:如果它是与对象的位置相同的实例,则只允许访问对象的受保护成员。代码或某个子类 - 即使它是由父类公开的。例如,假设你有:

class Parent
{
    protected int x;
}

class Child1 extends Parent
class Child2 extends Parent
class Grandchild extends Child1

Then within the Child1 code, you can access Parent.x only for objects which are known (at compile-time) to be instances of Child1 or Grandchild. You couldn't, for instance, use new Parent().x or new Child2().x.

然后在Child1代码中,只能为已知(在编译时)作为Child1或Grandchild实例的对象访问Parent.x.例如,你不能使用新的Parent()。x或new Child2()。x。

#2


No, private fields can be accessed even from other instances (within a method of the same class).

不,甚至可以从其他实例(在同一类的方法中)访问私有字段。

They cannot be accessed from subclasses, however, not even within the same instance.

但是,不能从子类访问它们,即使在同一实例中也是如此。

You provide getter methods to allow "outside" code to access fields in your class. Since it is up to you what getters you provide, how visible you make them, and how they are implemented, you can exercise a lot of control as to who can access the data and how.

您提供了getter方法,允许“外部”代码访问您班级中的字段。由于您可以获得所提供的getter,使用它们的可见性以及实现方式,因此您可以对谁可以访问数据以及如何访问数据进行大量控制。

Note that there does not really need to be a name field if there is a getName: it is entirely up to the implementation of the getter where that data comes from.

请注意,如果存在getName,则实际上不需要是名称字段:它完全取决于数据来自的getter的实现。

Even if the getter (or setter) just wraps a private field, it is good style to have these setters and getters (as opposed to allowing direct field access).

即使getter(或setter)只包含一个私有字段,拥有这些setter和getter(而不是允许直接字段访问)也是一种很好的方式。

#3


getName() should return the name (wheather field or some other "thing").

getName()应该返回名称(wheather字段或其他“东西”)。

#4


Even if a field/method is 'private', it can still be accessed/invoked via reflection unless you install a custom security manager that disallows that.

即使字段/方法是“私有”,仍然可以通过反射访问/调用它,除非您安装了不允许这样做的自定义安全管理器。

#5


The idea of encapsulation is to allow implementations of different units to vary freely. Although we talk of objects, for encapsulation we really mean a unit of code. In class-based languages, the unit of code is usually the [outer] class.

封装的想法是允许不同单元的实现*变化。虽然我们谈论对象,但对于封装,我们实际上是指一个代码单元。在基于类的语言中,代码单元通常是[外部]类。

It also happens that binary operations (such as equals) become daft without access within the same class. So private means private to the [outer] class, not private to the same class within the same instance.

如果在同一个类中没有访问权限,二进制操作(例如equals)也会变得愚蠢。私有对[outer]类是私有的,而不是同一个实例中同一个类的私有。

Accessor methods generally indicate bad design on anything but simple value objects (getters only). Objects should have behaviour, rather than just be a dumb collection of data. Move code that would be on the outside using getters to a method that is meaningful on the object. Hand on heart, 99% of the time getters just return a field value. There is relatively little value in making a field private if you are going to add a getter and setter.

访问器方法通常表示除了简单的值对象(仅限getter)之外的任何设计上的错误设计。对象应该有行为,而不仅仅是一个愚蠢的数据集合。使用getter将外部代码移动到对象上有意义的方法。亲自动手,99%的吸气剂只返回一个场值。如果要添加getter和setter,将字段设为私有的价值相对较小。

#6


Do objects encapsulate data so that not even other instances of the same class can access the data?

对象是否封装数据,以便即使是同一类的其他实例也无法访问数据?

Sure, if you are not using static members.

当然,如果你没有使用静态成员。

Extract from this link:

摘自此链接:

Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables

有时,您希望拥有所有对象共有的变量。这是通过静态修改器完成的。在声明中具有static修饰符的字段称为静态字段或类变量

#7


What are "accessor methods" in Java - methods like getName()?

什么是Java中的“访问器方法” - 像getName()这样的方法?

Yes - getFoo() and setFoo() are accessor methods for a "property" named foo - this is part of the JavaBeans specification. The reason why these are preferred over public fields is that they allow you to have only a getter (making the property read only), do additional bookkeeping (like calculating derived fields) and validation of set values (throwing e.g. a PropertyVetoException when the value is not acceptable).

是 - getFoo()和setFoo()是名为foo的“属性”的访问器方法 - 这是JavaBeans规范的一部分。这些优先于公共字段的原因是它们允许您只有一个getter(使属性只读),执行额外的簿记(如计算派生字段)和验证set值(当值为throw时抛出例如PropertyVetoException)不能接受的)。

The whole thing was originally intended to be used with GUI tools that would allow you to graphically configure and combine JavaBeans in order to "build applications". This turned out to be largely a pipe dream, but the concept of JavaBeans and properties has turned out to be useful for regular coding and become wide-spread.

整个过程最初旨在与GUI工具一起使用,这些工​​具允许您以图形方式配置和组合JavaBeans以“构建应用程序”。事实证明,这主要是一个梦想,但JavaBeans和属性的概念已经证明对常规编码有用并且变得广泛传播。

Many people misunderstand the concept and believe that "encapsulation" just means writing setters and getters for private properties instead of making them public - and then rightfully consider that idiotic. Encapsulation means not exposing the inner workings of a class at all except in tightly controlled ways. In good OO design, you should not have too many get methods and very few set methods in a class.

许多人误解了这个概念,并认为“封装”只是意味着为私有财产编写制定者和吸气剂而不是将其公之于众 - 然后理所当然地认为这是愚蠢的。封装意味着除了以严格控制的方式外,根本不暴露类的内部工作。在良好的面向对象设计中,你不应该在类中使用太多的get方法和很少的set方法。

#1


I don't tend to think of it in terms of one object having access to another, but rather what code has access to what data within an object.

我不倾向于用一个访问另一个对象的对象来考虑它,而是用什么代码可以访问对象中的哪些数据。

In Java (and C#, btw) code within a class has access to the private members of any object of the same class. Then you've got package/assembly access and public access.

在Java(和C#,btw)中,类中的代码可以访问同一类的任何对象的私有成员。然后你就有了包/程序集访问权限和公共访问权限。

The tricky one is protected access, which is sort of access to code in subclasses - but it depends on the target object: you're only allowed to access protected members of an object if it's an instance of the same type as the location of the code, or some subclass - even if it's being exposed by a parent class. So for instance, suppose you had:

棘手的是受保护的访问,它是对子类中代码的访问 - 但它取决于目标对象:如果它是与对象的位置相同的实例,则只允许访问对象的受保护成员。代码或某个子类 - 即使它是由父类公开的。例如,假设你有:

class Parent
{
    protected int x;
}

class Child1 extends Parent
class Child2 extends Parent
class Grandchild extends Child1

Then within the Child1 code, you can access Parent.x only for objects which are known (at compile-time) to be instances of Child1 or Grandchild. You couldn't, for instance, use new Parent().x or new Child2().x.

然后在Child1代码中,只能为已知(在编译时)作为Child1或Grandchild实例的对象访问Parent.x.例如,你不能使用新的Parent()。x或new Child2()。x。

#2


No, private fields can be accessed even from other instances (within a method of the same class).

不,甚至可以从其他实例(在同一类的方法中)访问私有字段。

They cannot be accessed from subclasses, however, not even within the same instance.

但是,不能从子类访问它们,即使在同一实例中也是如此。

You provide getter methods to allow "outside" code to access fields in your class. Since it is up to you what getters you provide, how visible you make them, and how they are implemented, you can exercise a lot of control as to who can access the data and how.

您提供了getter方法,允许“外部”代码访问您班级中的字段。由于您可以获得所提供的getter,使用它们的可见性以及实现方式,因此您可以对谁可以访问数据以及如何访问数据进行大量控制。

Note that there does not really need to be a name field if there is a getName: it is entirely up to the implementation of the getter where that data comes from.

请注意,如果存在getName,则实际上不需要是名称字段:它完全取决于数据来自的getter的实现。

Even if the getter (or setter) just wraps a private field, it is good style to have these setters and getters (as opposed to allowing direct field access).

即使getter(或setter)只包含一个私有字段,拥有这些setter和getter(而不是允许直接字段访问)也是一种很好的方式。

#3


getName() should return the name (wheather field or some other "thing").

getName()应该返回名称(wheather字段或其他“东西”)。

#4


Even if a field/method is 'private', it can still be accessed/invoked via reflection unless you install a custom security manager that disallows that.

即使字段/方法是“私有”,仍然可以通过反射访问/调用它,除非您安装了不允许这样做的自定义安全管理器。

#5


The idea of encapsulation is to allow implementations of different units to vary freely. Although we talk of objects, for encapsulation we really mean a unit of code. In class-based languages, the unit of code is usually the [outer] class.

封装的想法是允许不同单元的实现*变化。虽然我们谈论对象,但对于封装,我们实际上是指一个代码单元。在基于类的语言中,代码单元通常是[外部]类。

It also happens that binary operations (such as equals) become daft without access within the same class. So private means private to the [outer] class, not private to the same class within the same instance.

如果在同一个类中没有访问权限,二进制操作(例如equals)也会变得愚蠢。私有对[outer]类是私有的,而不是同一个实例中同一个类的私有。

Accessor methods generally indicate bad design on anything but simple value objects (getters only). Objects should have behaviour, rather than just be a dumb collection of data. Move code that would be on the outside using getters to a method that is meaningful on the object. Hand on heart, 99% of the time getters just return a field value. There is relatively little value in making a field private if you are going to add a getter and setter.

访问器方法通常表示除了简单的值对象(仅限getter)之外的任何设计上的错误设计。对象应该有行为,而不仅仅是一个愚蠢的数据集合。使用getter将外部代码移动到对象上有意义的方法。亲自动手,99%的吸气剂只返回一个场值。如果要添加getter和setter,将字段设为私有的价值相对较小。

#6


Do objects encapsulate data so that not even other instances of the same class can access the data?

对象是否封装数据,以便即使是同一类的其他实例也无法访问数据?

Sure, if you are not using static members.

当然,如果你没有使用静态成员。

Extract from this link:

摘自此链接:

Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables

有时,您希望拥有所有对象共有的变量。这是通过静态修改器完成的。在声明中具有static修饰符的字段称为静态字段或类变量

#7


What are "accessor methods" in Java - methods like getName()?

什么是Java中的“访问器方法” - 像getName()这样的方法?

Yes - getFoo() and setFoo() are accessor methods for a "property" named foo - this is part of the JavaBeans specification. The reason why these are preferred over public fields is that they allow you to have only a getter (making the property read only), do additional bookkeeping (like calculating derived fields) and validation of set values (throwing e.g. a PropertyVetoException when the value is not acceptable).

是 - getFoo()和setFoo()是名为foo的“属性”的访问器方法 - 这是JavaBeans规范的一部分。这些优先于公共字段的原因是它们允许您只有一个getter(使属性只读),执行额外的簿记(如计算派生字段)和验证set值(当值为throw时抛出例如PropertyVetoException)不能接受的)。

The whole thing was originally intended to be used with GUI tools that would allow you to graphically configure and combine JavaBeans in order to "build applications". This turned out to be largely a pipe dream, but the concept of JavaBeans and properties has turned out to be useful for regular coding and become wide-spread.

整个过程最初旨在与GUI工具一起使用,这些工​​具允许您以图形方式配置和组合JavaBeans以“构建应用程序”。事实证明,这主要是一个梦想,但JavaBeans和属性的概念已经证明对常规编码有用并且变得广泛传播。

Many people misunderstand the concept and believe that "encapsulation" just means writing setters and getters for private properties instead of making them public - and then rightfully consider that idiotic. Encapsulation means not exposing the inner workings of a class at all except in tightly controlled ways. In good OO design, you should not have too many get methods and very few set methods in a class.

许多人误解了这个概念,并认为“封装”只是意味着为私有财产编写制定者和吸气剂而不是将其公之于众 - 然后理所当然地认为这是愚蠢的。封装意味着除了以严格控制的方式外,根本不暴露类的内部工作。在良好的面向对象设计中,你不应该在类中使用太多的get方法和很少的set方法。