1

The following code illustrates the situation:

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

   }

 }

Here heart [private variable] of deb got modified unfortunately. :)

Java allows the code to run without any error.But is it justified to give a object the privilege to access private member of other object even if the code is in the same class ? Shouldn't Java disallow this?

As I know, private means restricting access beyond the class source code. But the same concept is applied in the source code above. and the result is disastrous since a person's heart can't be modified by any random person .

4

6 回答 6

5

如果结果是灾难性的,则不应对类进行编码以使其允许。“错误”不是由类外部的代码引起的,而是由类本身的代码引起的。所以这只是你代码中的一个错误。

如果 Java 不允许,您只能通过它们的公共属性来比较同一类的对象,例如,这会破坏封装(通过公开私有内容)和/或非常慢(通过强制制作防御性副本私有属性,使它们可用于其他对象。

于 2012-04-17T13:28:01.737 回答
2

一些语言在对象级别进行封装,而其他语言(Java、C++)在类级别进行封装。听起来您已经习惯(或刚刚阅读过)对象级别的封装。坦率地说,我发现类级别要自然得多,但也许这只是因为 C++ 为我提供了使用类进行编程的介绍。类级封装使一些习惯用法(工厂方法、复制构造函数、比较运算符)更容易编写。使用对象级封装,您最终会暴露比您真正想要的更多的东西,只是为了能够实现这些功能。

无论如何,这两种方式都不是“正确的”——它们只是不同而已。

于 2012-04-17T13:24:04.500 回答
0

查看防御副本以避免这种情况。这是因为 java 对象的操作更像引用。“指针”不会改变,但是一旦你知道它,你就可以改变它包含的值。

http://www.informit.com/articles/article.aspx?p=31551&seqNum=2

于 2012-04-17T13:24:23.710 回答
0

这并没有破坏面向对象——它是关于类内部元素的封装。

您可以使用此示例执行此操作似乎很愚蠢,但就我而言,这实际上并不是一件坏事。封装类元素的目的是让其他类无法修改它们——它们只能看到类的公共接口,Human例如进行更改。这意味着不止一个人可以在同一个项目上工作,编写不同的类(或者您可以在不同时间编写不同的类在同一个项目上工作),并且他们不需要知道代码的内部工作原理。

但是,您可以直接在 Human 中访问私有字段的唯一位置(条形反射)来自Human。当您编写 Human 类时,如果您选择对其他 Human 对象的私有字段进行修改,这取决于您 - 但它都包含在一个类中,这是您的设计。如果您以不合适的方式执行此操作,那么这是您的设计中的一个缺陷,而不是 Java - 在某些情况下,这样做非常有意义!

于 2012-04-17T13:27:39.350 回答
0

好吧,我看到它的方式,这只是我对 private 关键字的解释,private 是类私有的,可以在类内部访问。它不限于类的实例。因此,您不能在“humantest”类中​​执行 kate.heart="xpto",因为这会试图破坏它的隐私,但是允许使用 kate 的代码来改变 deb 的心脏,因为它是在类内部处理的。

于 2012-04-17T13:29:14.450 回答
0

Java 语言严格遵循面向对象的概念。这也是正确的..对吗?使用您的类的对象,您正在修改您的类的变量。但这取决于可以控制他的对象的程序员。

Human 的心在 Human 的类中是私有的。但是使用控制方法,您可以从外部访问它。这就是它被修改的原因..那有什么问题.?

于 2012-04-17T13:30:52.110 回答