Private nested Java class in UML diagram - java

I have a question regarding UML. I have a class which simply contains an inner class with the private access modifier - cannot be accessed from anywhere else... Normally in order to present an inner class relation I can use a (+) relation like here (InnerOddIterator):
(taken from http://www.uml-diagrams.org/nested-classifier.html)
I have not found anywhere any information about how can clearly emphasize that this class is private. Do you know if such a method exist at all? If yes I'll be grateful you give me some link here or something?
Just to keep things clear, a sample code:
public class DataStrucure {
// fields, methods, etc
private class InnerOddIterator{
// ...
};
}

From UML point of view. If classifier (Class also) is nested in other class, nesting class plays role of namespace. In this case nested classes are hidden (private) in context namespace. it means, your diagram implicitly defines private inner class definition.
here is part of definition from UML Superstructure section structred classifiers:
"A class acts as the namespace for various kinds of classifiers defined within its scope, including classes. Nesting of
classifiers limits the visibility of the classifier to within the scope of the namespace of the containing class and is used for
reasons of information hiding. Nested classifiers are used like any other classifier in the containing class."

First of all: You have something in your code and asking for an UML representation. But, IMHO, you should look at it the other way round: How can that UML-idea be represented in code. (Some programming languages don't even offer private nested classes...).
As for private nested classes: I suggest using a Composition. It is stronger as Association but not as strong as inheritance. And the composed class can not exist without its composer. Pretty much exactly a private nested class.
The drawing is taken from http://www.uml-diagrams.org/association.html:

In order to indicate that your inner class is privete the best, for me, is to use - character as depicted below but of course in this case you miss the internal structure of your inner class..

Related

Java: Is there a way to put nested classes in a separate file?

I have a Java class that is about 4,000 lines long (lots of methods). This class then uses about 200 small classes that only it needs, so another 4,000 lines of code.
If this was C# I would put those other in a partial class file so different file, but they would remain private nested classes only visible to the parent class.
Is there a way to do this in Java? I'm not asking for some methods to be in a distinct file, but for private nested classes to be in a distinct file.
thanks - dave
You can't make a class private to only another class while putting it in a different file.
Use no class access modifier
What you can do is put the classes in separate files with no access modifiers (omit "public"), which will make them package-private, i.e. visible only within its own package. See also the official Access Control tutorial.
UtilClasses.java:
package OurPackage;
class UtilClass1
{
}
class UtilClass2
{
}
MainClass.java:
package OurPackage;
public class MainClass
{
UtilClass1 iAmAUtilClass;
}
Use interfaces or inheritance
You can also achieve something similar with either interfaces or inheritance, by omitting the access modifier from the nested class. This would also be package-private, but this might be preferable to the above in some circumstances, since it avoids having all the nested classes at the top level.
BaseInterface.java:
package OurPackage;
interface BaseInterface
{
class UtilClass1
{
}
}
MainClass.java:
package OurPackage;
public class MainClass implements BaseInterface
{
UtilClass1 iAmAUtilClass;
}
You can also use a base class instead of an interface and extend that with roughly the same effect.
You don't need to implement BaseInterface gain access to its nested classes, but, if you don't, you'd need to use BaseClass.UtilClass1 instead of just UtilClass1.
Inner private classes can't be "extracted" and still be visible only to one particular class. One solution is already mentioned in the comments: Create a package that contains the "main" class and all the previously inner classes and make the inner classes package visible. This would also allow you to create unit tests testing for the correct functionalities of the inner classes, which is something that is most likely currently not happening simply because the inner classes can't be "reached" by a unit test at the moment.
Concepts like declaring "friendships" between classes like in C++ don't exist in Java.
You can replace the inner classes with top-level ones, but you'll have to rewrite a lot of things by hand that the compiler auto-wires for you with the inner-class relationship. To the Virtual Machine, an inner class is nothing special, it's just another class in the same package as the outer class with a fancy name. But the compiler creates a lot of helper constructs under the hood, that you have to reconstruct by hand (or have some refactoring tool do that for you):
The inner class can refer to the outer this instance, by prefixing it with the outer class name. You need to pass the outer this into your inner constructor and store it in a field like outerThis to get access.
In the source code, you can call the outer-class methods directly. You need to rewrite it like outerThis.method(). The same applies to fields.
For private outer methods and fields to become accessible, the compiler creates bridge constructs for you. You have to either change access modifiers or create package-private bridge methods yourself.
In the end, you'll have the former inner classes at least package-visible and being more verbose than the original ones, but on the other hand you'll get better isolation and testability.

Understanding inner classes (Why inner classes exist) [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was reading Thinking in Java, about why inner classes exist and what problem they help solve.
The most compelling reason the book tries to give is:
Each inner class can independently inherit from an implementation.
Thus, the inner class is not limited by whether the outer class is
already inheriting from an implementation.
Please help review my understanding:
Inner classes exist since Java doesn't support Multiple Inheritance. This (multiple inheritances) can be done within an Inner class which it is that the Outer class can have multiple inner classes, and each of them can inherit from different classes. So in this way, The multiple inheritances can be implemented. Another reason I can think of is Inner classes address the OOP design principle composition better than inheritance.
Updated
Most of the explanation I found just like the answers below. for example, Inner class used in the GUI framework to deal with the event handler. Not mentioned the reason quoted in the book.I am not saying the answers below are not the good. Actually. I really appreciated them(+1). I just want to know Is there something problem with the book?
It is a little puzzling why you thought of the idea of multiple inheritance after reading the most compelling reason you have quoted from the book. Multiple inheritance comes into question when a class (inner or not) wants to inherit behavior from more than one concrete implementation. Thus, unlike some other languages, in Java, you can not define a class like:
class Child extends Father, Mother {
// Child wants to inherit some behavior from Father and some from Mother
}
As you can see, nothing that only inner classes do can rectify or work around this Java decision (not to support multiple inheritance) in a straightforward way.
Then why do they exist, you may wonder! Well, in Java every class is either top-level or inner (also called nested). Any class that is defined inside another class is an inner class and any class that isn't so is a top-level class.
Naturally, one might wonder why to define classes (i.e. behavior) inside other classes. Aren't top-level classes enough?
The answer is yes. Java could always have only top-level classes. But the idea (perhaps) was there was no good reason to restrict classes from being members of other classes! Just like any predefined type (e.g. Integer, String etc.) can be a member of a class:
class Person {
private String name; // a field the models a Person's name
}
a programmer should be able to define a behavior of one's interest inside the class:
class Person {
private String name; // a field the models a Person's name
private Address address; // address is a type defined here
static class Address {
String street;
String city;
}
}
There's a lot going on here, especially with these things like private, static etc. which are called the modifiers. There are many technical details about them, but let us come back to them later. The essential idea is to be able to define behavior as a part of another class. Could the Address class be defined outside Person class, as a top-level class? Of course. But having this facility comes in handy.
Now, since this facility was introduced, it started serving another purpose and that purpose is called providing code as data. This is how design patterns emerge and it was thought until about 10 years ago that inner classes can be used to provide the data in the form of code. Perhaps this is somewhat puzzling to you. Consider the following code that I have taken almost verbatim from the JDK class: java.lang.String.java:
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String> {
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
// details excluded for brevity
// return -1, 0, 1 appropriately
}
}
What has happened here?
We need a way to compare a String to another String and we need to be able to do a case-insensitive comparison. So, we created an implementation of the Comparator interface right inside the outer class: String! Isn't this handy? If inner class wouldn't be there, this would have to be:
public class String {
// ... the whole String class implementation
}
class CaseInsensitiveComparator
implements Comparator<String> {
// implements the comparator method
}
and that's not 'bad' per se, but it means a lot of classes polluting the name space. Inner classes restrict the scope of a behavior to the outer class. That comes in handy, as you'd perhaps see. The data in this case is the implementation of the Comparator interface and the code is well, the same, because we are _new_ing up the inner class we defined.
This feature was exploited further using the anonymous inner classes (especially in the cases where you wanted the code to serve as data) up until Java 7 and they were effectively replaced by Lambda Expressions in Java 8. Nowadays, you might not see any new code that uses anonymous inner classes (in other words, language evolves).
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one
place: If a class is useful to only one other class, then it is
logical to embed it in that class and keep the two together. Nesting
such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B,
where B needs access to members of A that would otherwise be declared
private. By hiding class B within class A, A's members can be declared
private and B can access them. In addition, B itself can be hidden
from the outside world.
It can lead to more readable and maintainable code: Nesting small
classes within top-level classes places the code closer to where it is
used.
Oracle Documentation: Understanding inner classes
Below SO question might be interesting to you -
What is the reason for making a nested class static in HashMap or LinkedList?
UPDATE
Not mentioned the reason quoted in the book. ... I just want to know
Is there something problem with the book?
I don't think there is any problem with the statement you have highlighted.
Each inner class can independently inherit from an implementation: That's true right. Just like an outer class, it can inherit from an implementation independently. Just think both of them as separate class.
Thus, the inner class is not limited by whether the outer class is already inheriting from an implementation: As both are separate class, it doesn't matter whether outer class is already inheriting from an implementation. Inner class can inherit from an implementation too. After all it's a class too.
If you are looking for use-cases, I can only tell you what I use them for frequently, which are basically these 2 things:
Static inner classes I use for helping to implement some internal logic. These are usually some form of tuples, or some simple containers. For example: Maps have "Entries" in them which are basically just pairs.
Representing runtime parent-child relationships. These are non-static inner classes. For example: I have a Job class which may instantiate multiple Task inner classes that need to see the data in the job for their processing.
There may be more use-cases of course...

Use case for multiple top-level Java classes in a single file?

Is there a legitimate use for non-nested classes in Java? For example:
MyClass.java:
final class NonNestedClass {
...
}
public class MyClass {
private NonNestedClass nonNested;
...
}
As far as I can tell, this is equivalent to having a static nested class under MyClass. NonNestedClass cannot access the fields of MyClass. Is there any difference, and more importantly, is there a legitimate use of this paradigm?
Is there any difference[?]
Yes.
A non-nested class, even if in the same file, is an independent, top-level class. It has no special relationship to the file's eponymous class.
Nested classes can access the members of the class in which they're nested, and vice-versa. (If the nested class is static, it needs an instance of the outer class to access the instance's fields.)
Nested classes can be accessed by name from other compilation units. But typically only the eponymous top-level class can be accessed by name from other compilation units.
And more importantly, is there a legitimate use of this paradigm?
It supports backwards compatibility with files written in Java 1.0, before nested classes were introduced in version 1.1. That was about 20 years ago now. This case doesn't come up very often.
Other than that, I've personally never found need of it. The typical pattern is to put a class and its auxiliary classes in a single file.
References
Nested classes introduced in version 1.1 -- The best reference I could find still accessible online is this copy of Appendix D of "The Java Programming Language."
The optional constraint on multiple top-level type declarations in a single file -- Java Language Specification, Section 7.6: "Top Level Type Declarations".
Accessibility of private members of top-level class and its nested auxiliary classes - Java Language Specification, Section 6.6.1: Determining Accessibility".
I often use it in test code, it helps to be able to keep everything in a single file, but I don't know if that qualifies as a valid use case.

use private to specify access control of a class

I have been reading Thinking in Java from Bruce Eckel these days, when comes to the Access Control chapter, it says if a java file has two or more classes, except the public one, others can not be private (that would make it inaccessible to anyone but the class) or protected.
But I have seen a lot of popular java libraries and open source projects did have used private to decorate these kind of classes.
So is it because the book too theoretical or any reason else?
the original text (page 231, forth edition)
Note that a class can not be private (that would make it inaccessible to anyone but the class) or protected. So you have only two choices for class acess: package acces or public. If you don`t want anyone else to have access to that class, you can make all the constructors private, thereby preventing anyone but you, inside a static member of the class, form creating an object of that class.
The statement is only true for top-level (non-nested) classes. Nested classes may be private. That's because top-level classes have visibility into private nested classes (including the private members of a nested class), and vice versa. They may also be protected, meaning subclasses of the enclosing class, even in another package, can reference them.
Note that this isn't unique to Java files that declare more than one top-level class. private and protected are not allowed on any top-level class declaration.

Java. Nested classes with static member. How can we circumvent it?

My question is: it's known that nested class cannot have a static member (only if the class isn't described as static). But sometimes we need to have it.
Ex: we have a library. It has books (we will consider books as the inseparable part of library, I just can't guess about another example).
In class Library I should describe nested private class Book. Nested because Book exists only in a Library(as I described before). Private because we want to permit creation book outside of the Library. I want to have counter of all books, stored in all libraries. I simple situation I should have static counter, but there I can't. And I can't describe Book as static class because Book belongs to the Library.
Your reasoning for having a nested class doesn't really make sense.
If you really want Book to only be accessible by library, you can declare it package private by putting it in a package with library and declaring the class to be private.
That way, only library can use the class.
e.g.
package com.company.library;
private class Book {
}
The reason you can't have a static member in Book is that a Book is a non-static member of Library. As such, the Book class has an implicit reference an enclosing class instance (an instance of Library). You have a number of options:
Make the Book class static.
Keep the static counter in the Library class instead.
Make Book a completely separate class from Library altogether. A library instance can keep a counter of how many books it holds.
I personally think #3 is the better option. A Book should not be forced to be in a library, it should also be allowed on a CoffeeTable. :P
If you want to have a counter of all books in all libraries, I would rather ask each library for its count of books, and total the lot.
I think this is much better handled by asking the libraries for info about what they contain. The libraries look after their books, and the responsibility lies with them. Maintaining that shared state outside the libraries breaks encapsulations (and depending on the implementation, may introduce you to pain when concurrently updating etc., if you choose to do that in the future).
Remember that one of the points of OO is to tell objects to do things for you.
I'm not sure about your assertion re. books existing only in a library. They belong to a library, but that's slightly different. Your books can be standalone objects (not necessarily inner classes), and perhaps your libraries should contain a book factory, that creates a book with a reference to the owning library. Check out the Factory pattern for more info.
Nested (non-static) classes in Java tend to be a generally confusing concept. I would recommend against using them, unless you really know what you are doing, and have a convincing need (since other people having to maintain your code will also have to understand it). Nested classes are a kind of dark corner of the language, which it is always possible to avoid.
In general, the use case for making a class nested, is when the class is only used by the outer class. For example, the Library may have a CardCatalog, which is internal to the Library, and which never interacts directly with users of the Library. Even then, it will often be less confusing, if you make the relationship between them be slightly more explicit, by making the CardCatalog a static inner class, and passing it a Library instance in its constructor. Besides everything else, it will be more testable.
I can understand the problem that you mentioned but tell me something.The mapping of Library to book is One to many. That is one Library can have many books.So in my opinion this could be handled better if you have a Separate library class and separate books class. You can have an arrayList associated with Library class of type Book eg:
Class Library { private ArrayList<.Books>; }
such kind of thing would help you to solve the problem in a better way. For keeping a count of the book have a count class that will be associated with each book instance same way as we have the Library to Books.
Is this what you mean?
class Library {
private static long allBooksInAllLibraries;
private class Book {
private Book() {
// this should be synchronized if threads are involved
allBooksInAllLibraries += 1;
}
}
}
Non-static nested lasses are really meant for cases where there is only one instance of the nested class per instance of the outer class. This is clearly not the case in your example.
Therefore you should either convert Book to a static nested class, or pull it out and create a regular class (this is the better option). You can restrict the access to it, by making it protected or package private (by just defining it with class Book).

Categories

Resources