Private interfaces inside the class

Here I came across this phrase:

Implementing a private interface is a way to force the definition of methods on that interface without adding type information (that is, without allowing any promotion).

Itโ€™s hard for me to understand this. Can anyone explain this to me?

+5
source share
5 answers

The examples in the related article are a bit far-fetched and artificial (as the odd names A , B , etc. have already indicated). However, let me focus on the part of the quote your question refers to:

"... without adding type information (that is, without the permission of any promotion).

A class can offer several (public or private) implementations of this interface. But the key point:

No one can ever understand that they implement this interface .

Just because the interface is not public.

I tried to create an example showing a possible application case. Of course, this is still far-fetched, but it may make the point more obvious. Suppose you want to simulate a Tree data structure consisting of Node objects. These can be InnerNode objects (which have child nodes) or LeafNode objects (which have no children).

Such a class can be implemented as follows:

 class Tree { // The private interface private interface Node { List<Node> getChildren(); } // Both are public implementations public class InnerNode implements Node { @Override public List<Node> getChildren() { return Arrays.<Node>asList(getLeafNode(), getLeafNode()); } } public class LeafNode implements Node { @Override public List<Node> getChildren() { return Collections.emptyList(); } } // These return the concrete, public types public InnerNode getInnerNode() { return new InnerNode(); } public LeafNode getLeafNode() { return new LeafNode(); } // This returns the private interface type public Node getRootNode() { // Both concrete types can be returned here, // because they both implement the interface return getInnerNode(); // Works //return getLeafNode(); // Works } // This uses only the interface type public void traverseNode(Node node) { System.out.println("Traversing "+node); for (Node child : node.getChildren()) { traverseNode(child); } } } 

In the external main method, you can observe the restrictions imposed by the private interface:

 public static void main(String[] args) { Tree tree = new Tree(); // The public concrete types can be used Tree.LeafNode leafNode = tree.getLeafNode(); Tree.InnerNode innerNode = tree.getInnerNode(); // The private interface can not be used from outside: //Tree.Node node = tree.getRootNode(); // This is possible: The class only uses its // own private interface here tree.traverseNode(tree.getRootNode()); } 

In this example, you can call traverseNode , passing in the Node that getRootNode returns, regardless of whether this node is InnerNode or LeafNode . In the current version, it will print something like

 Traversing Tree$InnerNode Traversing Tree$LeafNode Traversing Tree$LeafNode 

If you changed getRootNode to return a LeafNode , then it will only print

 Traversing Tree$LeafNode 

Simply put, and as the name "private interface" already says: you can use this to hide the fact that the two classes share a common ancestor.

+1
source

Here is an example of private interfaces.

 public class Main { private interface Animal { void makeNoise(); } public static final class Cow implements Animal { @Override public void makeNoise() { System.out.println("Moo!"); } } public static final class Sheep implements Animal { @Override public void makeNoise() { System.out.println("Bah!"); } } public static void main(String[] args) { List<Animal> animals = Arrays.asList(new Cow(), new Sheep()); for (Animal animal : animals) animal.makeNoise(); } } 

In the Main class, you can call Animal and call makeNoise() on it. Therefore, you can have a List from Animal different types and use for each loop to call makeNoise() on all of them.

However, outside the Main class, this is not possible. You can have a Cow or Sheep and call makeNoise() , but the Animal interface and the makeNoise() interface method are invisible.

+4
source

I researched this question and was able to find information about more . Below is a practical example

enter image description here

The SaveInterface class is a type (i.e., a Class without an implementation, all its methods are abstract). It has one public user function called SaveData (). The document class from the original solution now implements the SaveInterface type so that the SaveData () method is not accessible to Document clients.

Note that in this solution, SaveHandler does not have a navigational link to the Document class. This has been replaced by a shipping association with the SaveInterface Class. Since SaveData () is declared publicly in SaveInterface, the SaveHandler class does not need to be declared as a friend of the Document class.

Since the SaveHandler class is not a friend of the Document class, it does not have the ability to modify any of its private member variables or call any of its personal member functions. Thus, the encapsulation of the Document class is preserved. The SaveHandler class no longer needs to know about the Document class since it now depends on an interface called SaveInterface. This reduces overall design dependencies and creates potential for reuse.

Members

Purpose (document)

  • defines the public interface for the client.
  • creates a RequestHandler object (SaveHandler) and passes an instance of RequestInterface (SaveInterface) to the RequestHandler instance. - In a motivating example, the Document class exports an interface that allows clients to run asynchronous saves.

Client

  • Customers
  • use the exported Target interface to perform specific functions.

Command

  • the command line interface is used because it is likely that the Target interface will want to create many different types of RequestHandler Objects. If all of these objects implement the interface command, then Factory2 can be used to create individual RequestHandler objects.

RequestHandler (SaveHandler)

  • created with reference to RequestInterface. implements the Command Interface so that the Target class can call the Execute () element to execute the request.

  • in the motivation example, the SaveHandler class is used to create a separate thread of execution, and then call a specific member function in SaveInterface to actually save the data in the document to the newly created thread.

RequestInterface (SaveInterface)

  • indicates an abstract interface for a particular request.

enter image description here

Known use

This pattern is widely used in the Xerox real-time embedded environment. it is used to break the thread of performance in classes that perform various services for their customers.

For more information: http://www.objectmentor.com/resources/articles/privateInterface.pdf

+1
source

A private interface is a way to force a class to implement some methods without publicly disclosing that this interface is implemented - for example, you cannot create a List<MyPrivateInterface> and add instances of your class to it.

0
source

I think the question is, why do you want to โ€œforceโ€ your own class to implement something? I mean, this is your class, if you want it to implement a method, just implement it. "Private INTERface" is simply the wrong name. An interface is a view of your class that you want to expose from the outside. Make it private impractical.

If you ask about "private" packages, this is a bit different, although not very. Sometimes you may need to implement an interface that is internal to your implementation and not exposed to external influences. It is quite difficult (although not impossible) to come up with an example where it would be useful.

0
source

Source: https://habr.com/ru/post/1209602/


All Articles