Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use inner class in practical [closed]

Why would someone use an inner class? The same functionality can be achieved with a local class or subclass.

An example would also be appreciated.

like image 630
Birju088 Avatar asked Aug 14 '13 17:08

Birju088


1 Answers

Inner classes can be used in many functional cases. They present two advantages:

  1. An inner class can see fields of the outer class (if it is not static). That means you don't have to deal with the outer class fields as if they come from an outer class. This implies your inner class needs an instance of the outer class to work. If you class is static, then it behaves as an independent class.
  2. An inner class is tightly related to its owning class. So even if it's static, you know by its name that it is related to its owning class.

With this said, you can understand that inner classes have to be used where things belong together.

So the most probable case is when you don't need the inner class outside of the outer class. ex:

class ScreenCapture {
  class CaptureButtonListener implements ClickListener {
     public void onClick( ClickEvent click ) {
       //..capture
       pressCount++;
     }
  }

  Button button = new Button("capture");
  int pressCount = 0;

  void addListeners() {
    button.addClickListener( new CaptureButtonListener() );
  }
}

As you can see:

  • you will never need CaptureButtonListener outside of ScreenCapture. So it's better off to hide it (and even declare it as private or protected).
  • The inner class is accessing a field that is not belonging to it: pressCount. This is possible because its instance is tied to ScreenCapture instance : you cannot create new CaptureButtonListener() in a static method: you're obliged to use it in the instance methods.

On the other hand, the static inner class is just for organisation purposes (to say both classes are related). I'll adapt the previous example with a static inner class:

public class ScreenCapture {
  public static class CaptureButtonListener implements ClickListener {
    protected ScreenCapture controller;
    public CaptureButtonListener( ScreenCapture controller ) {
      this.controller = controller;
    }

     public void onClick( ClickEvent click ) {
       //..capture
       controller.pressCount++;
     }
  }

  Button button = new Button("capture");
  int pressCount = 0;

  public void captureRequested() {
    //do capture...
    pressCount++;
  }

  void addListeners() {
    button.addClickListener( new CaptureButtonListener(this) );
  }
}

Notice that in this case:

  • the variable pressCount is not accessible from the inner class anymore: you have to specify the instance it belongs to.
  • You can instantiate CaptureButtonListener from outside, but you see directly from its name: new ScreenCapture.CaptureButtonListener( screenCaptureInstance ) that it's related to the ScreenCapture class (which improves code readability)

Now you may wonder why you would create an inner class that cannot access its owner fields? you're right: this is not very wise in our case since you're obliged to pass an instance of ScreenCapture to the constructor (so you cannot use it with any other class than ScreenCapture). It was just to demonstrate the difference.

The following example will give the previous one all its sense:

You can declare your listener as a public static interface inside ScreenCapture

class ScreenCapture {
  public static interface class CaptureRequestListener {
     public void captureRequested( ClickEvent click );
  }
}

This way you could pass ScreenCapture implementations of "how to handle a capture request"

Again, implementations of the interface will know they are implementing something specific to ScreenCapture since they will implement

public class MyImpl implements ScreenCapture.CaptureRequestListener {
  public void captureRequested( ClickEvent click ) {
    // I will count requests instead
  }
}

Your code is therefore clearer than having it in separate class per file organisation.

You can also have a base handling class (an abstract implementation of common tasks as an inner class)

I hope everything was clear :-) Best regards, Zied

like image 65
Zied Hamdi Avatar answered Nov 05 '22 13:11

Zied Hamdi