2

我怎样才能将成员字段设为此特定对象的私有字段?即该对象可以读取和修改该值,但同一类的其他对象不能。

例如

class Person 
{
    // don't mind sharing these with other persons :
    private integer houseNumber;
    private integer telephoneNumber;

    // would like this to be *really private*
    // (only visible / modifiable to this instance)
    private integer bankBalance;


    // Lots of code for interaction with other persons:
    // (e.g. maintained by co-workers)

    void interact1(Person person)
    {
        //Lots of code
    }

    void interact2(Person person)
    {
        //Lots of code
    }

    //...

    void interactN(Person person)
    {
        //Lots of code
    }
}

我了解 Java 的“私有”访问意味着访问仅限于此类中的代码。从概念上讲,类中的所有代码都在我的控制之下,所以我对此负责。控制 Person 对象对其他 Person 对象的作用应该是我的责任。

但是假设我有大量与其他人交互的方法,我希望编译器为我做检查,而不是亲自搜索代码。也许这个 java 文件是与同事共享的,并且经常更改。

我的问题是 - 如何在 Java 中实现“对此对象的私有”访问?有没有一种理智/明智的方式来实现它?

编辑 - 重新强调目标

我想要几行类设计/代码,以保证其他 Person 对象无法读取/写入属于该实例的 bankBalance。我知道它并不是真正为 Java 设计的——但这是我的动机的一部分,看看一般来说实现它的最干净的方法是什么。我真的希望编译器强制执行它 - 我不是在寻找涉及审核所有函数的解决方案,确保它们只调用正确的 getter / access 方法。

4

5 回答 5

5

假设您的目的是防止意外而不是恶意,您可以创建一个单独的 BankBalance 类来跟踪谁拥有余额:

class BankBalance {
    private int bal;
    private Person belongsTo;
    public BankBalance (int initialBalance, Person belongsTo) {
        this.bal = initialBalance; this.belongsTo = belongsTo; 
    }
    public int getBalance (Person calledBy) {
        if (calledBy != belongsTo) throw new RuntimeException ("no peeking");
        return bal;
    }
}

class Person {
    private BankBalance bal;

    void checkBalance () {
        if (bal.getBalance(this) > 1000) ...
    }
}

任何使用getBalance都需要调用者通过this. 我认为这可能会使意外编写访问另一个人的余额的代码变得更加困难。您还可以将 BankBalance 设为嵌套类,并检查calledBy != Person.this而不需要显式belongsTo字段,但这将允许interact1引用person2.bal.balbal在 BankBalance 中设为私有仍然不会阻止封闭类访问它)。也许这仍然足以防止事故发生。

于 2013-08-05T16:46:41.410 回答
1

正如每个人都指出的那样,没有真正的方法可以做到这一点。你可以做类似表格的吸气剂

private int getBankBalance(Object caller) {
     if (caller == this) {
          return bankBalance;
     } else {
          throw new RuntimeException("GTFO");
     }
}

然后强制所有访问都通过object.getBankBalance(this).

但是,这并不能阻止人们bankBalance直接访问或调用object.getBankBalance(object).

于 2013-08-05T16:31:49.677 回答
0

您可以声明一个包含每个 Persons 余额的余额数组列表。像这样的东西:

static int instances = 0;
private int thisInstance = 0; 
private List<Integer> balances = new Arraylist<>();

public Person() {
   instances++;
   thisInstance = instances;
   balances.add(thisInstance, new Integer(0));
}

然后,每当您有与 交互的代码时,bankBalance您只需返回与调用它的实例相同的元素。

例如,如果第五个实例试图获取它的余额,该方法将返回数组中的第五个余额。

例如:

private int getBankBalance() {
   return balances.get(thisInstance).intValue();
}

这样一来,任何试图获取银行余额的人都只会退还他们的余额,而他们看不到其他人的余额。

于 2013-08-05T16:05:57.423 回答
0

我不相信您所采取的方向是正确的,如果我是您,我会尝试从不同的角度看待事物,您提出的要求是一个奇怪的要求。

如果您需要的是禁止其他对象的属性访问,您将无法实现这一点。如果为它指定一个 getter 并使用它来引用该属性,则可以这样做。

实例由其属性标识,因此您可以编写一个检查某些属性的方法,然后使用它来确定某个对象是否可以访问该属性访问器。

所以总结起来会是这样的:

private boolean isBankBalanceAccessible() {
    // check that properties are those you want,
    // for example only when houseNumber is 1234567890
    return houseNumber == 1234567890;
}

private int getBankBalance() {
    if (isBankBalanceAccessible()) {
        return bankBalance;
    } else {
        // maybe throw here?
    }
}
于 2013-08-05T16:06:05.283 回答
0

我想到了这个...

     void interact1(Person person)
      {
         if(this==person)
          {
             person.bankBalance
             // Do here with the balance of the objecct which calls this function
          }


          //rest code here
      }

希望它有效..!!

于 2013-08-05T16:31:25.253 回答