Thursday, August 25, 2011

Java Nested Inner Classes

Nested Classes

The Java allows to define a class within another class. Such a class is called a nested class a

Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes.

class OuterClass {
		...
		
		static class StaticNestedClass {
			...
		}
		
		...
		
		class InnerClass {
			...
		}
		
		...
	}

A nested class is a member of its enclosing class.

Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.

Static nested classes do not have access to other members of the enclosing class.

As a member of the OuterClass, a nested class (static and non-static) can be declared private, public,protected, or package private. (Recall that outer classes can only be declared public or package private.)

Why Use Nested Classes?

It is a way of logically grouping classes that are only used in one place.
It increases encapsulation. Example: kind of entry class in hashmap.
Nested classes can lead to more readable and maintainable code.

Static Nested Classes

A static nested class is just like any other top-level class.

It cannot access variables and members of outer class directly.

Only way to interact with the instance members of its outer class (and other classes) just like any other top-level class - but creating an object of outer class and then accessing its members and variables.

For example, to create an object for the static nested class, use this syntax:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Inner Classes

It has direct access to outer object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.
An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Additionally, there are two special kinds of inner classes: local classes and anonymous classes (also called anonymous inner classes).

Local and Anonymous Inner Classes

There are two additional types of inner classes. You can declare an inner class within the body of a method. Such a class is known as a local inner class. You can also declare an inner class within the body of a method without naming it. These classes are known as anonymous inner classes.

public class MyClass {
	public A myFunction() {
		return new A() {
			private int i = 11;

			public int getValue() {
				return i;
			}
		}; // Semicolon required in this case
	}

	public static void main(String[] args) {
		MyClass p = new MyClass();
		A c = p.myFunction();
	}
}

interface A {
	int getValue();
}




package main.java.concepts;


// wrong - >
// import main.java.algo.faaltoo;
// imports are checked and validated at compile time.

	//	Why Use Nested Classes?
	//
	//		It is a way of logically grouping classes that are only used in one place.
	//		It increases encapsulation. Example: kind of entry class in hashmap.
	//		Nested classes can lead to more readable and maintainable code.


// fyi - top level class can be only public OR default
// and name of top level class is the name of .java file
public class NestedInnerClasses {
	
	public static void main(String[] args) {
		OuterClass outerObj = new OuterClass();
		
		// A nested class is a member of its enclosing class.
		
		// instantiate static nested
		OuterClass.StaticNestedClass statNestClass = new OuterClass.StaticNestedClass();
		
		//instantiate non-static inner
		OuterClass.InnerClass innerClass = outerObj.new InnerClass();
	}
	
	
	// anonymous local classes
	public ABC getAnon() {
		
		return new ABC() {
			public int getVal() {
				return 0;
			}
		}; // semi-colon required
		
	}
	
}

interface ABC {
	public int getVal();
}


class OuterClass {
	
	private int outerPrivVal = 10;
	public int outerPubVal = 20;
	
	private void outerPricFxn() {
		System.out.println("In Outer Private Function");
	}
	
	public void outerPubFxn() {
		System.out.println("In Outer Public Function");
	}
	
	public void doJob() {
		OuterClass.StaticNestedClass statNestClass = new StaticNestedClass();
	}
	
	// static nested classes are just like any top level class
	// Static nested classes do not have access to other members of the enclosing class.
	// Only way to access it is via object of Outer, just like any other top level class.
	// via object, it can access even private members. This is not possible via any top level class. Can be only done in nested static class.
	static class StaticNestedClass {
		
		public void staticNestedClassFxn() {
			OuterClass outerObj = new OuterClass();
			outerObj.outerPrivVal = 13;
			outerObj.outerPubVal = 23;
			outerObj.outerPricFxn();
			outerObj.outerPubFxn();
		}
		
	}
	
	// inner class can access all members of outer class
	// this class can be public/private/protected/dafault - but if private - cannot be accessed outside outerclass. - if protected, cannot be accessed outside this pkg and any classes extending outer.
	class InnerClass {
		
		public void innerClassFxn() {
			outerPrivVal = 15;
			outerPubVal = 25;
			outerPricFxn();
			outerPubFxn();
		}
		
	}
	
}


References -

http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

No comments:

Post a Comment