Java是否完全遵循面向对象的编程模型?

时间:2012-04-17 13:20:30

标签: java oop object jvm private

以下代码说明了这种情况:

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不应该禁止这个吗?

据我所知,私有意味着限制访问超出类源代码。但是在上面的源代码中应用了相同的概念。结果是灾难性的,因为一个人的心脏不能被任何随机的人修改。

6 个答案:

答案 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语言严格遵循面向对象的概念。这也是正确的......正确的?使用类的对象,您正在修改类的变量。但它可以控制他的对象的程序员。

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