Getting Inside With Inner Classes
by (11 December 2000)



Return to The Archives
Introduction


Java has been popular for quite a few years, and has been a major target of consideration for game developers especially. This article will be focusing on one of the very strong points of Java: the importance and usage of inner classes. Before I proceed further there is a small assumption that is necessary about you which will not only make it easier for me, in terms of providing in-depth coverage of the topic, but will also allow me to take this step further while dealing with issues involved in its usage.

You have been programming with Java for at least quite sometime now, which gives the impression that you know which one of the following statements is wrong.

  • import java.awt.*;
  • public abstract final class MyClass extends SomeOtherClass
  • private void SomeMethod(int arg1,int arg2,char arg3)


  • What Is An Inner Class?


    An inner class from its own perspective is nothing but a class that has been defined inside another class. For example

    
    [Example 1]
    	class Outer
    	{
    		class Inner
    		{
    			
    		}
    	}
     


    The most interesting thing about them is that they are not only visible inside the class but with the use of proper access modifier we can allow them to be used inside/outside the class and inside/outside the package. There are a couple of points that are common between different types of inner classes (Described later) so itís a good point to discuss them.

  • There is no relationship (Inheritance) between Outer and Inner class, until and unless you explicitly specify one.
  • An inner class can access all the private resources (Methods/Properties) of the Outer class.
  • Now as we know what are they, letís see what are different types of inner classes available (Yeah there are different types of inner classes). The type not only specifies the syntax but also specifies its usage restriction.

    Type 1 [Defining an inner class inside a class]

    This is the standard type (see example1) where we can specify a class inside another class. We will be dealing mostly with these types in this article. The following points need to be considered:
  • Access to Inner class is available inside the class.
  • The access modifier used will decide availability of Inner class, outside the class/package.
  • Type 2 [Defining an inner class inside a method]

    This type specifies the definition of an inner class inside a method such as

    
    [Example 2]
    	class Outer
    	{
    		public void SomeMethod()
    		{
    			class Inner
    			{
    			}
    		}
    	}
     


    The point of consideration here is, that the existence of class Inner is only available when we call SomeMethod(). This point specifies the following issues

  • class Inner is not available outside the method SomeMethod() even inside class Outer.
  • You can not specify an access modifier with a class of this type.
  • The first point is self-explanatory but the later requires a little detail. An access modifier specifies the rights to a class/object. With this type of inner class the method SomeMethod() specifies the boundaries (scope) as it specifies for any ordinary object. With the concept of scope around there is no point to further restrict or elaborate the restriction rights by specifying an access modifier.

    Type 3 [Defining an inner class inside a method-Anonymous Classes]

    This is basically an enhanced version of Type-2 class. An Anonymous class as the name suggests doesnít have a name, which creates some suspicious opinions regarding this article; but before I deal with them, consider the following example

    
    [Example 3]
    	class MyFrame extends Frame
    	{
    		Button m_btn=new Button(ďClick MeĒ);

    public MyFrame() { //Ö After some initialization add(m_btn);

    m_btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); } }


    At this point it does appear that at addActionListener something really obnoxious has been done but in fact this is our anonymous class. Letís take a brief tour with it. The first point that is necessary to understand about this type of inner class is that they donít have any usual declarations like

    [AccessModifer] class [ClassName]

    Instead they begin with an impression that we would like to create a temporary instance of any class. Next we specify the base class/interface which acts as the parent class for our anonymous class (In Example3 we have specified that our anonymous class will implement the interface ActionListener). Following are the points that do require attention

  • It must either extend a class or implement an interface but it canít do both like a usual inner class.
  • You canít specify an access modifier.
  • You canít specify a constructor. Why?? well simple, they donít have any names.
  • If you would like to call a different constructor of the base class then you can simply specify it at the creation time. For example

    
    SomeObj.SomeMethod(new SomeClass(45)
    {
    	//Your anonymous class extending from SomeClass
    });
     


  • An anonymous class can only access final variables of the method in which it was specified.


  • How To Use An Inner Class


    Now that we know about different types of inner classes, lets see how we can actually create an instance of an Inner class. To create an instance of a non-private, non-static inner class you need to have an object of outer class. Such as

    
    		Outer 		objOuter = new Outer();
    		Outer.Inner 	objInner = objOuter.new Inner();
     


    The point here is simple, just like a normal non-private, non-static object, we need to have an object of outer class to assist in the creation of inner class. With the use of qualified operator (.) we have specified the clear distinction between an Inner class defined inside a class called Outer and an Inner class defined at the source file level.

    For a non-private, static class the requirement is same as that of an object, i-e you can simply create an object of a static inner class without explicitly creating an object of an outer class. Such as

    
    		Outer.Inner	objInner = new Outer.Inner();
     


    What Is So Special About Them?


    We have seen lots of examples of inner classes in the areas of event handling by applying anonymous classes but what is the most prominent point that should make a normal rookie to prefer them instead of using a simple class? I would like to answer this question by giving certain scenarios that will justify my opinion.

    Scenario-1 In case of creating dialogs wouldnít it be better if I can somehow contain my entire event handling inside my dialog class. Well what do you know inner classes to the rescue!!! You can create your event handling classes inside your class and by providing the private access modifier you can restrict outside interference.

    Scenario-2 Have you ever faced a situation when you are trying to communicate a child dialog with a parent window? No need to send the whole object of your parent class in order to get notification, you can simple provide your child dialog as an inner class of your parent and thus can access even the private member methods.


    A Game Development Perspective


    Well shouldnít this article be about applying inner classes while developing my next 3d FPS? Well yes, with the knowledge so far we can utilize the mechanism and can provide certain behaviors to our enemies or NPC (Non-Player Character) by not only placing them in the object hierarchy but by also leveraging the power of inner classes.


    One Last Point


    I know, I know.. the next email that will be coming to me will be regarding ďHow to get a reference of Outer class inside my Inner Class?Ē Well the answer is simple but a little tricky. We know that an inner class can access the private member variables of the outer class so letís exploit this behavior and consider the following example.

    
    		class Outer
    		{
    			private Outer		m_OuterThis;
    			
    			public Outer()
    			{ m_OuterThis = this;}

    class Inner { void SomeMethod() { // Utilize (m_OuterThis) } } }


    Conclusion


    Well I think this article should push you into the strange world of inner classes, so let me know what else you discover there by sending me an email: saad_faisal@c4.com.

     

    Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
    Please read our Terms, Conditions, and Privacy information.