Function only visible to a specific class
Hi All
I am implementing a tree hierachy with a classes call 'Tree" and "Node". Inside the Node class, I have a function call "setName" for setting the name of the node. This function will only ever be used by Tree for setting the name of the nodes inside the tree. Is there anyway I can make the restriction so that this function will only ever be visible to the class "Tree" only?
[396 byte] By [
chungkpa] at [2007-10-2 4:04:00]

As was mentioned before, the closest you can come to the access-level restriction that you want is to make the method in Node package-private. This will, however, let any other classes in the package still call it.
There is one workaround using reflection. Again, not perfect. You can make the method in Node private and have Tree call it using reflection. You would first need to call AccessibleObject.setAccessible(true) on the Method instance returned by reflection. This would be more inefficient than calling a method directly, and you still would have no way to prevent other classes from using reflection to call the method (though this is true generally of any Java method).
What you are looking for is something analogous to the C++ 'friend' access modifier. However, this sadly does not exist in Java.
Finally, you could try and use a feature of inner classes to achieve your aim. An enclosing type can call the private methods of an inner class. You would do something like:
public class Tree {
ModifiableNode node;
private void someMethod() {
node.setFoo();
}
class ModifiableNode extends AbstractNode {
private void setFoo() {
}
}
}
interface Node {
abstract void getFoo();
}
abstract class AbstractNode implements Node {
public void getFoo() {
}
}
- Saish
Saisha at 2007-7-15 23:26:40 >

It also depends the way you want to model your Tree/Node concepts.
In particular you will often hear something along the lines of: "if the setName function is only Tree's business, then it should be a method of Tree itself".
You could object that even if this method is implemented in Tree, you need a way to associate the name to the corresponding object held in the tree.
But stuffing the name in the Node itself is maybe not the right way: if the name property does not belong to the entity held in the node (if the name concept is only relevant to the Tree), then it could be stored in another attribute of the Tree class (such as a Map of names keyed by the path).
Now if you want other classes to read that name (but not set it), you have several options:
1) If your Node class only represent the building block of a tree structure (with the wiring, management of children, etc...),
then other classes maybe don't need to see it : if they want to know the data at a certain node in the tree, they can ask the tree, something along Tree.getDataAtpath(...)..
Even if these other class need other things like getNumberOfChildren, and especially getNameAtPath(...), you can write your Tree class to provide these services.
Note that I assummed above that you have a path notion, independant of the name data, to identify nodes in the tree structure, otherwise you wouldn't need to read the name from the Tree. In case your client classes can get a Node reference without knowing about the Tree or the path in the Tree, you probably fall in case 2.
2) Now if your Node class represents the building block of a tree structure PLUS the data it contains:
First note that this model is not very flexible because it mixes the wiring of a tree structure with the business logic of the entity contained in the tree structure.
But one way you can model it is to separate the concerns in two interfaces (say, GenericNode and MyNodeData), implemented by the same NodeImpl class, and expose only MyNodeData to the outside. If your setName method belongs to the GenericNode, tree can invoke it but client classes will not even know it exists.
Note that this doesn't protect against malicious calls (client code could simply cast the reference to GenericNode or NodeImpl). It just protects from accidental usage. It reminds the convention that "only Tree should set the name", but does not enforce it.
What do you think of a pedantic generalization such as:
The Java replacement to C++'s friend concept is to spread functionalities among interfaces.?
You should be able to make the node a public static inner class of the Tree class with setName as a private method.
Or you can create a special NameHolder type that only Tree has access to and use that to pass the name.
Or as said earlier you can have the node call Node#getName(Tree tree) where node can pull its name from the tree.
But this philosophy will just tie you in knots time and time again. I would say let this go. Make the method package scope, and don't break your own rules. Don't let your program execution sequence dictate your class design. Either the object can have its name set or it can not. If any class can do it (other than this) then the whole package can do it. If you fight that, youll have a hard time in Java.