|
Mark Davis / http://www.macchiato.com/ |
Durable Java | Immutables | Abstraction | Serialization | Liberté, Égalité, Fraternité | Hashing and Cloning
These are simply a couple of follow-up remarks after I discontinued my column.
I recommend a couple of interesting and relevant articles on equality by Klaus Kreft & Angelika Langer in Java Solutions. In particular, Implementing equals for Mixed-Type Comparison improves on my mechanisms for implementing equality across different classes.
Java does not have the friend keyword from C++. There is, however, a way to emulate that; a way that actually gives a lot more precise control. Suppose that you have classes A and B. B needs access to some private method or field in A.
public class A {
private int privateInt = 31415;
public class SomePrivateMethods {
public int getSomethingPrivate() { return privateInt; }
private SomePrivateMethods() {} // no public constructor
}
public void giveKeyTo(B other) {
other.receiveKey(new SomePrivateMethods());
}
}
public class B {
private A.SomePrivateMethods key;
public void receiveKey(A.SomePrivateMethods key) {
this.key = key;
}
public void usageExample() {
A anA = new A();
//int foo = anA.privateInt; // doesn't work, not accessible
anA.giveKeyTo(this);
int fii = key.getSomethingPrivate();
System.out.println(fii);
}
}
The usageExample() shows how this works. The
instance of B doesn't have access to the private fields or
methods of an instance of A. But by calling the giveKeyTo(),
class B can get access. No other class can get access to that
method, since it a requires a valid B as an argument.
The class B can then use any of the methods that
are handed to it in the key. This, while clumsier to set up than the C++
friend keyword, but is much more fine-grained. The class A can
chose exactly which methods to expose to exactly which classes.
Now, in the above A is granting access to all
instances of B and instances of subclasses of B.
If the latter is not desired, then the giveKeyTo() method can
internally check the exact type of other with getClass(),
and throw an exception if it is not precisely B.