以下代码说明了这种情况:
class Human {
private String heart = "default heart";
public void control(Human h) {
h.heart = "$%^&*@@!#^";
}
public String getHeart() {
return heart;
}
}
public class HumanTest {
public static void main(String[] args) {
Human deb = new Human();
Human kate = new Human();
System.out.println(deb.getHeart());
kate.control(deb);
System.out.println(deb.getHeart());
}
}
不幸的是,deb的心脏[私有变量]被修改了。 :)
Java允许代码在没有任何错误的情况下运行。但是,即使代码在同一个类中,给对象提供访问其他对象的私有成员的权限也是合理的吗? Java不应该禁止这个吗?
据我所知,私有意味着限制访问超出类源代码。但是在上面的源代码中应用了相同的概念。结果是灾难性的,因为一个人的心脏不能被任何随机的人修改。
答案 0 :(得分:5)
如果结果是灾难性的,则不应对类进行编码以使其允许。 “bug”不是由类外部的代码引起的,而是由类本身的代码引起的。所以这只是代码中的一个错误。
如果Java不允许它,你只能通过它们的公共属性比较同一类的对象,例如,它会破坏封装(通过暴露私有东西),和/或非常慢(通过强制制作)私有属性的防御性副本,使其可供其他对象使用。
答案 1 :(得分:2)
某些语言在对象级别具有封装,在类级别具有其他语言(Java,C ++)。听起来你已经习惯了(或刚刚读过)封装在对象层面。坦率地说,我发现类级别更自然,但也许这只是因为C ++提供了使用类编程的介绍。类级封装使得一些习语(工厂方法,复制构造函数,比较运算符)更容易编写。使用对象级封装,您最终会暴露出比您真正想要的更多,以便能够实现这些功能。
无论如何,两种方式都不是“正确” - 它们只是不同。
答案 2 :(得分:0)
调查防御性副本以避免这种情况。这是因为java对象的操作更像引用。 “指针”不会改变,但一旦你知道它就可以改变它所包含的值。
http://www.informit.com/articles/article.aspx?p=31551&seqNum=2
答案 3 :(得分:0)
这不是打破面向对象 - 它是关于类内部元素的封装。
你可以用这个例子做到这一点似乎很愚蠢,但就我看来它实际上并不是一件坏事。封装类的元素是为了让其他类不能修改它们 - 它们只能看到类Human
的公共接口以进行更改。这意味着不止一个人可以在同一个项目上工作,编写不同的类(或者你可以在不同的时间编写不同的类来处理同一个项目),而且他们不需要知道代码的内部工作原理。
但是,您可以直接在Human中访问私有字段的唯一地方(条形反射)是来自 Human。当你编写Human类时,如果你选择修改其他Human对象的私有字段,这取决于你 - 但它都包含在那个类中,这是你的设计。如果你以一种不合适的方式做到这一点,那么它就是你设计中的一个缺陷,而不是Java - 在某些情况下这样做非常有意义!
答案 4 :(得分:0)
嗯,我看到它的方式,这只是我对private关键字的解释,private是类的私有,可以在类中访问。它不限于该类的实例。因此你不能在“humantest”类中做kate.heart =“xpto”因为那会试图破坏它的隐私,但是允许使用kate的代码来改变deb的内心,因为它是在类中处理的。
答案 5 :(得分:0)
Java语言严格遵循面向对象的概念。这也是正确的......正确的?使用类的对象,您正在修改类的变量。但它可以控制他的对象的程序员。
人类的内心在人类的内心是私人的。但是使用控制方法,您可以从外部访问它。这就是它被修改的原因。那是什么问题。?