I am reviewing the concept of inner classes in java. so far from what I've understood and applied java inner classes has a link or access to the methods and fields of its outer/ enclosing class.
My Question:
When should create or define an inner class?
are inner classes considered to be called as "Helper classes" ?
What are the indicators for you to make an inner class and what's their other purpose?
Inner classes are best for the purpose of logically grouping classes that are used in one-place. For example, if you want to create class which is used by ONLY enclosing class, then it doesn't make sense to create a separate file for that. Instead you can add it as "inner class"
As per java tutorial:
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one
place.
It increases encapsulation.
It can lead to more readable and maintainable code.
A classic use for an inner class is the implementation of an iterator inside a container (ArrayList, for example - look for class Itr). All the container wants to expose to the rest of the world is an Iterator. However, it has to create some concrete implementation of that iterator, possibly familiar with the internals of the container. Using an inner class hides the implementation, while keeping it close to the container's implementation. And being inner (i.e. non-static), it is bound to a specific instance of that container, which lets it access private container members.
There are a few types of inner classes - non-static nested class, local classes and anonymous classes. Each one has a somewhat different purpose, so when asking about an inner class, you should specify what kind are you talking about.
Assuming you're referring to non-static inner classes, I'd say the reason to use them is the same as using regular classes (namely abstraction and dividing code into logical units), but there's no reason to make this use of classes visible to the rest of the world. You can also make nested classes public, of course, in which case you'd make them nested instead of independent in order to express their tight relation with the outer class.
See the Java tutorial for the main reasons.
If by "helper class" you mean something for internal use only, then no, not necessarily. You might want to do something like
class Outer {
private static class Inner implements InterestingInterface {
// whatever
}
public InterestingInterface make_something_interesting() {
return new Inner();
}
}
Here, Inner is not a "helper class" in the sense that the outside world does get to see instances of it, but its implementation is entirely hidden -- the outside world only knows it gets some object that implements InterestingInterface.
As a general rule, objects should be designed for a single responsibility (Highly cohesive). In other words, any object designed well, should perform a single coherent task. This would be considered best practice for object orientated design.
Sometimes, however, a developer may design a class that requires a separate specialized class in order to work. This separate specialized class could be considered a helper class.
If the helper class is not used by any other class, then it would be considered a prime candidate as an inner class
As elicited by ncmathsadist above, an example of inner class use would be in the implementation of Event handlers.
For example, in designing a graphical user interface (GUI), a developer may have created a button that performs a particular task after the user presses it.
The button would need an event handler which listens for when that particular button is pressed.
In this case, creating the event handler for the button as an inner class would be best practice as the inner class would not be utilized anywhere else other than with the specific button within the GUI class.
One purpose of inner classes is to attach listeners. For example, suppose you have a JMenuItem. You can make it quit your app as shown in this code:
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//cleanup code before exiting
System.exit(0);
}
});
You may also want a class to have access to outer class state variables which is entirely subservient to that class. For example, consider writing a simple color calculator. It might have a text area into which you type a hex code. When you hit enter, you want a JPanel to display the color. Here is a crude outline of what you might do.
public class ColorCalc extends JPanel implements Runnable
{
Color displayedColor;
JTextArea colorEnterArea;
public ColorCalc()
{
displayedColor = Color.white
colorEnterArea = new JTextArea();
}
public void run()
{
//build GUI here
}
public static void main(String[] args)
{
ColorCalc cc = new ColorCalc();
javax.swing.SwingUtilities.invokeLater(cc);
}
//subservient inner class with access to outer class state variable.
class ColorPanel extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(displayedColor);
g.fillRect(0,0,getWidth(), getHeight());
}
}
}
This is a style question. Anything that can be done with an inner class can also be done as a as series of external classes. Inner classes are especially useful for classes that are lightweight or tightly bound to the enclosing class. For example, a comparator is frequently both these things. It needs intimate knowledge of the implementation of the class, and may only be a few lines long. It may be an ideal candidate as an internal class.
If you find that there is enough code which could be better done by class as class provides us to specify stats and
behavior with fields and methods and you don't want this class needs to be used outside of enclosing class. you should use inner class.
Here the inner class is hidden from the outside world.
Inner class can access the private member of enclosing class which provides us encapsulation.
Let me give example..
Suppose you want to set the gear to cycle and you have a business rule like there are only up to 6 gears.
So you can create Inner Class Cycle which would have a method to set the gear.
That method has some validation which are checked before setting gear.like the cycle is running...gear number is less than 6...
best example is event handling code uses inner classes(sometimes anonymous inner classes) to create events and listeners without creating separate Event Object and Event Listener classes for your event..
The inner class used for grouping classes logic, for example, if you have class B and this class used only at class A, So it is better to put class B as an inner class at class A, as this will give readability and reusability for your code.
Happy code :)
Adding from my personal notes, for future visitors:
Sources: https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
Lets say you have a type and its a class, called OuterClass, in a package called "com.custom.classes".
Then here is how you begin to need an inner class or static class:
Case 1:
you need to package a group of classes
but also kind of need certain global variables exposed to all these classes at that package level
you understand you can do no such things with packages but realise that you could achieve this with inheritance, where the parent class members can act as global variables that become available for all of its child class instances.
but you don't like the idea that you need to inherit the parent class and also that you need to instantiate the child class to access the global variables. Thats like asking to buy a coffee shop in order to have a coffee.
and so you realise that you can create an OuterClass with the static members and house all the classes in this OuterClass as inner class or static class as needed and lo! The OuterClass static members become available as global variables for these nested classes and you could even access them without instantiating them.
This code should explain better
public class InnerClassTester{
public static void main(String []args){
// without the need to instantiate any class
// static class without instantiation
System.out.println(OuterClass.NestedStaticClass1.incrGlobalNum()); // outputs 1
// static class instantiated
OuterClass.NestedStaticClass2 koolObj = new OuterClass.NestedStaticClass2();
// works with instantiation as well
System.out.println(koolObj.incrGlobalNum()); // outputs 2
// inner classes always need to be instantiated
// and they can only be instantiated from within an instance of outer class
// think of them as instance member of outer class and this would make sense
OuterClass.NestedInnerClass1 koolObj2 = new OuterClass().new NestedInnerClass1();
// works with inner classes as well
System.out.println(koolObj2.incrGlobalNum()); // outputs 3
}
}
class OuterClass{
// global variable thats only accessible for select classes (or nested classes)
// we also learn a purpose for private static fields
private static int privateGlobalValue = 0;
// classes to be grouped
// static class
public static class NestedStaticClass1{
// no need to instantiate this class to access/update the global value
public static int incrGlobalNum(){
return ++privateGlobalValue;
}
}
public static class NestedStaticClass2{
// instantiate and still manipulate the global value
public int incrGlobalNum(){
return ++privateGlobalValue;
}
}
// inner class
public class NestedInnerClass1{
// instantiate and still manipulate the global value
public int incrGlobalNum(){
return ++privateGlobalValue;
}
}
}
Does this remind you of closures in Javascript ? :)
Most applications of nested classes see it being applied on basis of design decisions. What that means is, every case of a nested class can be replaced with other designs.
But having said that, it is also true that we can also replace the inheritance pattern with composition pattern (and it is gaining momentum lately) although an inheritance pattern is definitely better when the dependencies between the classes is so much so that composing the dependencies entirely would be ugly.
Case 2:
you need to implement 2 interfaces, IShark and IMosquito, with the same signature, a public bite method, on the OuterClass.
but you want to display 2 different messages since a shark's bite is a tad different from that of a mosquito's.
however you know that's not possible since only one bite method can be implemented
you know you can create 2 different classes in the same package that implement either interfaces and also implement separate bite methods and have them composed in OuterClass.
but you wanted to get it done within OuterClass because it was your design decision to encapsulate the bite behaviour within it, maybe because there was a dependency on a private variable within the class.
soon you realise you can implement both the interfaces via private static inner classes and make it appear to the outside world as though it was composed.
Take a look at this code:
// no additional classes in the package
public class InterfaceTester{
public static void main(String []args){
// same class returns 2 instances - both compliant to
// either interfaces and yet different output
IShark shark = OuterClass.getSharkInstance();
System.out.println(shark.bite()); // outputs "Die fast bosedk!"
IMosquito mosquito = OuterClass.getMosquitoInstance();
System.out.println(mosquito.bite()); // outputs "Die slow bosedk!"
}
}
interface IShark{
public String bite();
}
interface IMosquito{
public String bite();
}
class OuterClass implements IShark{
// dependency of inner class on private variable
private static String dieSlow = "Die slow bosedk!";
private static String dieFast = "Die fast bosedk!";
private static OuterClass outerInst;
private static InnerClass innerInst;
// private constructor to stop regular instantiation
private OuterClass(){}
// get a shark !
public static IShark getSharkInstance(){
return outerInst != null ? outerInst : new OuterClass();
}
// get a mosquito !
public static IMosquito getMosquitoInstance(){
return innerInst != null ? innerInst : new InnerClass();
}
// an implementation of bite
public String bite(){
return dieFast;
}
// inner class that implements the second interface
private static class InnerClass implements IMosquito{
// different implementation of bite
public String bite(){
return dieSlow;
}
}
}
These kind of design decision cases are numerous and all of the answers above list several such cases. So it would not be wrong to think that this feature was introduced more as a new pattern than as a feature or functionality.
Conceptually inner classes can be used to represent types in the universe that would not exist without that parent type. In other words, with a language that allows inner classes, the types are all 'type definers'. A type can then be considered something that explicitly or implicitly defines new types.
For example, imagine we have a universe where "Food" can be applied to anything. Even itself. Food is a fundamental concept in our universe. We introduce a subclass of Food called Meat. Without that concept, there is no such thing as "Meat Eater". So we can (note 'can') define a nested type "Meat.Eater" (which could implement an IEater interface) and define animals as being a containment structure of lists of different IEaters.
Once we remove Meat from the universe, Meat Eater disappears to.
This same philosophy applies neatly to more abstract and technically useful arrangements such as Mementos in the Memento Design Pattern , a configuration object defined as a nested class, and other type-specific behaviours or structures.
It also increases encapsulation because inner classes can be declared private.
I would just consider that this is just a feature of language. I would not recommend to use it if we adopt OOD and obey the SOLID principle.
Related
I have 2 classes A and B.
class A implements Constants{
private int state;
}
class B implements Constants{
foo(){
//want to set state variable of class A like this
state = state1
}
}
interface Constants{
public final int state1;
public final int state2;
}
I don't want to have an instance of class A in class B. How should I do this?
If I have a function to set the variable in the interface, then both the classes must implement this function. That would be wrong right? Because then 2 definitions for the same function would conflict?
There is nothing called functions in java. They are methods.
You can have getters and setters in your classes for the properties to set and get them from external classes.
Your question is unclear.
If your B class extends the A class, then through the constructor of the B class, you can set the properties of the A class that is the super class.
Hope it helps!
Having an interface does not mean that the variable will be shared between the classes, it is more of a way to define classes that MUST override the functions in the interface. You can read the very basics on them here. To share a variable between two classes, you can either make the variable static and put it in another class that both your classes extend (in effect a global variable, which is bad practice and not thread safe), or have one of the classes have an instance of the other and call getters/setters.
EDIT: there is a similar question here that shows you what I mean about the static variable.
You generally want to avoid writing any method in a class that attempts to alter the internal state of another class. Whatever trick you come up with to accomplish such a thing, you are breaking the principle of encapsulation which is the whole reason for using classes in the first place.
If there is some state that you wish to have accessible from multiple classes, I would recommend breaking that state out into it's own class and have each of the two classes interact with it through getter/setter or utility methods.
The Java tutorials that I read, like to use nested classes to demonstrate a concept, a feature or use.
This led me to initially implement a sample project I created just like that: Lots of nested classes in the main activity class.
It works, but now I got a monstrous monolithic .java file. I find it somewhat inconvenient and I now intend to break to multiple .java files/classes.
It occurred to me, however, that sometimes there may be reasons not to take classes out of their enclosing class.
If so, what are good reasons to keep a module large, considering modularity and ease of maintenance?
Are there cases in which it is impractical (or even impossible) to convert a nested class to a toplevel class? In other words, is there a case in which only a nested class could satisfy certain functionality?
It can be easier to read all the classes if they are in the same file. This is why this approach is good for example code.
However for real code, you should break your files/classes into manageable sizes. The longest class file in Java 6 is about 9000 lines long. I tend to keep classes shorter than this. ;)
a non-static nested class has an implicit reference to the creator instance of the enclosing class, and also it can access every member of the enclosing class (even private members). You lose this if you make the nested class top-level:
public class Outer {
private String s;
public void setS(String s) {
this.s = s;
}
public class Inner {
public String getOuterS() {
// This is legal only if Inner is
// non-static and nested in Outer
return s;
}
}
}
public class Main {
public static void main(String[] args) {
Outer o = new Outer();
o.setS("Hello world!!!");
// i now has access to every o member
Outer.Inner i = o.new Inner();
// Prints "Hello world!!!"
System.out.println(i.getOuterS());
}
}
Yes. Inner classes (non-static nested classes) may refer to instance variables of the containing class.
Also, nested classes may access private members of the containing class.
In addition to the benefit of closure (already pointed out in an other answer), nested classes also help you achieve multiple implementation inheritance (ref: Thinking in Java, page 369 - section "Why inner classes"?). As far I know, there is no other way to achieve it. So, if your nested class is helping you achieve multiple implementation inheritance, then it would not be possible for you to make the nested a top-level class.
Nested classes allow you to cleanly separate some functionality that belongs to the outer class and at the same time keep that functionality close to the outer class. In such cases, nested classes provide the best option from a design perspective and that alone can be the reason for not making it a top-level class (which can lead to class pollution in the main package).
Consider this (anonymous):
speakBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}});
vs. this: (non-anonymous):
class MyOuterClass {
private class MyOnClickListener implements OnClickListener {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
// later (inside some method)...
speakBtn.setOnClickListener(new MyOnClickListener());
}
Except for the fewer number of lines, is there any other advantage to the anonymous form?
Is there a performance advantage?
The anonymous inner class has advantage over the inner class (as in the question example code) in that it closes over the local variables of the method (although only final locals are usable).
Generally an inner class can be easily converted into a method with anonymous inner class, which helps reduce verbosity. If you've got an inner class that is so large that you want to make it non-local, you might want to think about battling with your IDE to put it in a new file as an outer class.
(The is also local classes, which are normal named inner classes defined within a method and that close over locals.)
The advantage to non-anonymous is that you can reuse the class. I believe the only reason to use an anonymous inner class is brevity.
Things I like about named inner classes:
They have a name. I find it easier to debug when I see MyOuterClass$MyOnClickListener in a stack trace instead of MyOuterClass$1, which is what you get with an anonymous inner class.
It sometimes helps readability to separate out the actual code for the inner class from the place you're using it. I especially like this if I'm already in a long method or indented more than a level or two.
To comment on your point about performance, anonymous inner classes get compiled into normal classes, so there should be no performance difference.
The advantage is the time you save as a developer for not having to type the extra keystrokes. :)
Oh, and it also prevents you from needlessly having to come up with a new name for everything (which may cause name collisions in some cases).
There is one disadvantage that pops out:
If you need more than one of the same inner class, you pretty much need to use an explicitly defined class. For what you describe, no you don't need one. But you may decide at a later date you need another object that does the same functionality, but is a different object.
The purpose of anonymous classes is make your required class as local. Anonymous classes are used when we are very much sure that a particular class A is the only consumer for a Class B and no where else this B class can be used .Then better we defined that class B as anonymous class inside Named class A. We are writing the required logic within the same class so avoiding the creation of object from outer side. It will easy to maintain in terms of code maintainability. So Anonymous classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
I have inherited code which contains static nested classes as:
public class Foo {
// Foo fields and functions
// ...
private static class SGroup {
private static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();
public SGroup(int id, String type) {
// ...
}
}
}
From reading SO (e.g. Java inner class and static nested class) I believe that this is equivalent to two separate classes in two separate files:
public class Foo {
// Foo fields and functions
// ...
}
and
public class SGroup {
static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();
public SGroup(int id, String type) {
// ...
}
}
If this is correct is there any advantage to maintaining the static nested class structure or should I refactor?
It depends on what the class is used for. If it's coupled to the outer class, for example, just like Map.Entry, just leave it in. However, if it makes sense to use the class without its enclosing type, you may as well promote it to a top level class.
Jorn statement is correct and it's usually manifests itself as the following rule of thumb:
Nested classes should be made private, Meaning that the hold auxiliary logic for the hosting class and nothing more. If you cant make them private- thet probably should not be nested.
The exception is when you define a nested class to allow easy access to the state of the hosting class, in that case you should consider simply merging both classes to increase cohesion.
It is not improper to say that "static nested classes" are not nested classes at all. It is convenient to discuss static nested classes in the context of inner classes because the way they are declared in code is similar and also because a static nested class still has to be named with the enclosing class as a context.
However, here is an important thing to keep in mind about static nested classes: from the point of view of the compiler and the JVM, static nested classes are top level classes. In fact, the compiler implements them logically at compile time as top level classes (at least it used to; I think it still does).
Why, then, should anyone ever use static nested classes? Why not just write top level classes all the time?
For me, static nested classes provide a convenient mechanism for logically grouping closely related classes in a manner that keeps my project hierarchy nice and tidy. For example, say that I have a database with the following tables: Clients, Encounters, and Services. I -could- model these tables with separate top-level classes and it would work fine, but since these tables are all in the same database and relate to the same data, I find it convenient to model these as:
class DB {
static class Client {
...
}
static class Encounter {
...
}
static class Service {
...
}
}
To use an instance of one of the models:
DB.Encounter enc = new DB.Encounter();
In my view, this makes code more readable since it is immediately clear in the code that the object that is being created derives from one of my database models. It also keeps the class definitions for the models linked under a common heading which I also think helps make projects simpler to understand.
But from the point of view of the JVM (and the compiler, which implements them as top level classes anyway [just as it also gives "anonymous" inner classes names at compile time]), these objects are instantiated from top level classes. Making them does not depend on any instance of any object, nor can objects instantiated from a static nested class access any private members of the enclosing class.
I like static inner classes as they provide loose coupling from the enclosing class (no access to private members of the enclosing class) static inner classes are also easy to promote to top level (because of the loose coupling attribute).
There is a simple rule of the thumb when to promote them:
If another class (other than the enclosing) needs to reference \ use the inner class.
I have just found a static nested interface in our code-base.
class Foo {
public static interface Bar {
/* snip */
}
/* snip */
}
I have never seen this before. The original developer is out of reach. Therefore I have to ask SO:
What are the semantics behind a static interface? What would change, if I remove the static? Why would anyone do this?
The static keyword in the above example is redundant (a nested interface is automatically "static") and can be removed with no effect on semantics; I would recommend it be removed. The same goes for "public" on interface methods and "public final" on interface fields - the modifiers are redundant and just add clutter to the source code.
Either way, the developer is simply declaring an interface named Foo.Bar. There is no further association with the enclosing class, except that code which cannot access Foo will not be able to access Foo.Bar either. (From source code - bytecode or reflection can access Foo.Bar even if Foo is package-private!)
It is acceptable style to create a nested interface this way if you expect it to be used only from the outer class, so that you do not create a new top-level name. For example:
public class Foo {
public interface Bar {
void callback();
}
public static void registerCallback(Bar bar) {...}
}
// ...elsewhere...
Foo.registerCallback(new Foo.Bar() {
public void callback() {...}
});
The question has been answered, but one good reason to use a nested interface is if its function is directly related to the class it is in. A good example of this is a Listener. If you had a class Foo and you wanted other classes to be able to listen for events on it, you could declare an interface named FooListener, which is ok, but it would probably be more clear to declare a nested interface and have those other classes implement Foo.Listener (a nested class Foo.Event isn't bad along with this).
Member interfaces are implicitly static. The static modifier in your example can be removed without changing the semantics of the code. See also the the Java Language Specification 8.5.1. Static Member Type Declarations
An inner interface has to be static in order to be accessed. The interface isn't associated with instances of the class, but with the class itself, so it would be accessed with Foo.Bar, like so:
public class Baz implements Foo.Bar {
...
}
In most ways, this isn't different from a static inner class.
Jesse's answer is close, but I think that there is a better code to demonstrate why an inner interface may be useful. Look at the code below before you read on. Can you find why the inner interface is useful? The answer is that class DoSomethingAlready can be instantiated with any class that implements A and C; not just the concrete class Zoo. Of course, this can be achieved even if AC is not inner, but imagine concatenating longer names (not just A and C), and doing this for other combinations (say, A and B, C and B, etc.) and you easily see how things go out of control. Not to mention that people reviewing your source tree will be overwhelmed by interfaces that are meaningful only in one class.So to summarize, an inner interface enables the construction of custom types and improves their encapsulation.
class ConcreteA implements A {
:
}
class ConcreteB implements B {
:
}
class ConcreteC implements C {
:
}
class Zoo implements A, C {
:
}
class DoSomethingAlready {
interface AC extends A, C { }
private final AC ac;
DoSomethingAlready(AC ac) {
this.ac = ac;
}
}
To answer your question very directly, look at Map.Entry.
Map.Entry
also this may be useful
Static Nested Inerfaces blog Entry
Typically I see static inner classes. Static inner classes cannot reference the containing classes wherease non-static classes can. Unless you're running into some package collisions (there already is an interface called Bar in the same package as Foo) I think I'd make it it's own file. It could also be a design decision to enforce the logical connection between Foo and Bar. Perhaps the author intended Bar to only be used with Foo (though a static inner interface won't enforce this, just a logical connection)
If you will change class Foo into interface Foo the "public" keyword in the above example will be also redundant as well because
interface defined inside another interface will implicitly public
static.
In 1998, Philip Wadler suggested a difference between static interfaces and non-static interfaces.
So far as I can see, the only difference in making an
interface non-static is that it can now include non-static inner
classes; so the change would not render invalid any existing Java
programs.
For example, he proposed a solution to the Expression Problem, which is the mismatch between expression as "how much can your language express" on the one hand and expression as "the terms you are trying to represent in your language" on the other hand.
An example of the difference between static and non-static nested interfaces can be seen in his sample code:
// This code does NOT compile
class LangF<This extends LangF<This>> {
interface Visitor<R> {
public R forNum(int n);
}
interface Exp {
// since Exp is non-static, it can refer to the type bound to This
public <R> R visit(This.Visitor<R> v);
}
}
His suggestion never made it in Java 1.5.0. Hence, all other answers are correct: there is no difference to static and non-static nested interfaces.
In Java, the static interface/class allows the interface/class to be used like a top-level class, that is, it can be declared by other classes. So, you can do:
class Bob
{
void FuncA ()
{
Foo.Bar foobar;
}
}
Without the static, the above would fail to compile. The advantage to this is that you don't need a new source file just to declare the interface. It also visually associates the interface Bar to the class Foo since you have to write Foo.Bar and implies that the Foo class does something with instances of Foo.Bar.
A description of class types in Java.
Static means that any class part of the package(project) can acces it without using a pointer. This can be usefull or hindering depending on the situation.
The perfect example of the usefullnes of "static" methods is the Math class. All methods in Math are static. This means you don't have to go out of your way, make a new instance, declare variables and store them in even more variables, you can just enter your data and get a result.
Static isn't always that usefull. If you're doing case-comparison for instance, you might want to store data in several different ways. You can't create three static methods with identical signatures. You need 3 different instances, non-static, and then you can and compare, caus if it's static, the data won't change along with the input.
Static methods are good for one-time returns and quick calculations or easy obtained data.