在 Java 中,
对象是否封装了数据,即使是同一类的其他实例也不能访问数据?仅在使用关键字“private”时?Java 中的“访问器方法”是什么 - 像 getName() 这样的方法?
谢谢
在 Java 中,
对象是否封装了数据,即使是同一类的其他实例也不能访问数据?仅在使用关键字“private”时?Java 中的“访问器方法”是什么 - 像 getName() 这样的方法?
谢谢
我不倾向于从一个对象可以访问另一个对象的角度来考虑它,而是认为哪些代码可以访问对象中的哪些数据。
在 Java(和 C#,顺便说一句)中,类中的代码可以访问同一类的任何对象的私有成员。然后你就有了包/程序集访问和公共访问。
棘手的是受保护的访问,这是对子类中代码的一种访问——但它取决于目标对象:只有当它是与位置相同类型的实例时,才允许访问对象的受保护成员代码或某个子类——即使它是由父类公开的。例如,假设您有:
class Parent
{
protected int x;
}
class Child1 extends Parent
class Child2 extends Parent
class Grandchild extends Child1
然后在Child1
代码中,您只能访问Parent.x
已知(在编译时)是Child1
or实例的对象Grandchild
。例如,您不能使用new Parent().x
or new Child2().x
。
不,甚至可以从其他实例(在同一类的方法中)访问私有字段。
但是,即使在同一个实例中,也不能从子类访问它们。
您提供 getter 方法以允许“外部”代码访问您类中的字段。由于您可以自行决定提供哪些 getter、使它们可见的程度以及它们的实现方式,因此您可以对谁可以访问数据以及如何访问数据进行大量控制。
请注意,如果有一个字段,则实际上并不需要一个name
字段getName
:这完全取决于该数据来自的 getter 的实现。
即使 getter(或 setter)只是包装了一个私有字段,拥有这些 setter 和 getter 也是一种很好的风格(而不是允许直接访问字段)。
getName() 应该返回名称(无论是字段还是其他一些“事物”)。
即使一个字段/方法是“私有的”,它仍然可以通过反射访问/调用,除非您安装了一个不允许这样做的自定义安全管理器。
封装的思想是允许不同单元的实现自由变化。尽管我们谈论的是对象,但对于封装,我们实际上是指一个代码单元。在基于类的语言中,代码单元通常是 [外部] 类。
在同一个类中没有访问权限的情况下,二进制操作(例如 equals)也会变得愚蠢。所以私有意味着对[外部]类私有,而不是对同一实例中的同一类私有。
访问器方法通常表明除了简单的值对象(仅限 getter)之外的任何东西的设计都不好。对象应该有行为,而不仅仅是一个愚蠢的数据集合。将使用 getter 的外部代码移动到对对象有意义的方法。认真对待,99% 的时间 getter 只返回一个字段值。如果要添加 getter 和 setter,则将字段设为私有的价值相对较小。
Java 中的“访问器方法”是什么 - 像 getName() 这样的方法?
是的 -getFoo()
并且setFoo()
是命名的“属性”的访问器方法foo
- 这是JavaBeans规范的一部分。这些优先于公共字段的原因是它们允许您只有一个 getter(使属性只读),进行额外的簿记(如计算派生字段)和验证设置值(例如,当值是时抛出PropertyVetoException不能接受的)。
整个东西最初打算与允许您以图形方式配置和组合 JavaBean 以“构建应用程序”的 GUI 工具一起使用。事实证明,这在很大程度上是一个白日梦,但 JavaBeans 和属性的概念已经证明对常规编码很有用并变得广泛传播。
许多人误解了这个概念,并认为“封装”只是意味着为私有属性编写 setter 和 getter,而不是将它们公开 - 然后理所当然地认为这是愚蠢的。封装意味着根本不暴露类的内部工作,除非以严格控制的方式。在良好的 OO 设计中,一个类中不应该有太多的 get 方法和很少的 set 方法。
对象是否封装了数据,即使是同一类的其他实例也不能访问数据?
当然,如果您不使用静态成员。
从此链接中提取:
有时,您希望拥有所有对象共有的变量。这是通过静态修饰符完成的。声明中带有 static 修饰符的字段称为静态字段或类变量