☰
Java allows you to define a class within another class. Such a class is called a nested class.
class OuterClass {
...
class NestedClass {
...
}
}
Nested classes are divided into two categories:Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
class OuterClass {
...
static class StaticNestedClass {
...
}
class InnerClass {
...
}
}
Non-static nested classes are also called inner classes. Inner classes are class within Class. Inner class is associated with its outer class. You have to create an instance of outer class to create an instance of an inner class.
public class OuterClass {
public class InnerClass {
}
}
This is how you create an instance of inner class.
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
Inner classes have access to the fields of the enclosing outer class, even if they are declared as private.
class OuterClass {
private String info = "Some private info";
public class InnerClass {
public void display() {
System.out.println(info);
}
}
}
Check how dispaly method of InnerClass references the private 'info' field of enclosing OuterClass.
class OuterClass {
private String info = "Some private info of outer class";
public class InnerClass {
private String info = "Some private info of inner class";
public void display() {
System.out.println(info);
}
}
}
Output:
Some private info of inner class
Here both the Outer and Inner class contains a field named 'info'.When the Inner class refers to info it refers to its own field. When Outer refers to info it also refers to its own field.class OuterClass {
private String info = "Some private info of outer class";
public class InnerClass {
private String info = "Some private info of inner classs";
public void display() {
System.out.println(info);
System.out.println(OuterClass.this.info);
}
}
}
Output:
Some private info of inner class
Some private info of outer class
There are 3 types of inner classes.
Member class is a class that is declared inside a class but outside a method.
There are two ways to invoke member class - Invoked from outside the class and Invoked within the class.
In the below code, I am invoking member class from outside the outer class.
class OuterClass {
class InnerMemberClass {
void display() {
System.out.println("Display method of
inner member class");
}
}
}
public class Demo {
public static void main(String[] args) {
OuterClass objOuter = new OuterClass();
OuterClass.InnerMemberClass objInner = objOuter.new InnerMemberClass();
objInner.display();
}
}
Output:
Display method of inner member class
Now we will invoke inside the outer class
class OuterClass {
class InnerMemberClass {
void display() {
System.out.println("Display method of inner member class invoked outside outer class");
}
}
void print(){
InnerMemberClass objInner = new InnerMemberClass();
objInner.display();
}
}
public class Demo {
public static void main(String[] args) {
OuterClass objOuter = new OuterClass();
objOuter.print();
}
}
Output:
Display method of inner member class invoked outside outer class
Local class is a class that is created inside a method.
class OuterClass {
void print() {
class InnerMemberClass {
void display() {
System.out.println("Display method of local inner class");
}
}
InnerMemberClass objInner = new InnerMemberClass();
objInner.display();
}
}
public class Demo {
public static void main(String[] args) {
OuterClass objOuter = new OuterClass();
objOuter.print();
}
}
Output:
Display method of local inner class
There are some rules for local classes.
class OuterClass {
void print() {
int x = 2;
final int y = 5; //local variable must be final
class InnerMemberClass {
void display() {
System.out.println("Display method of local inner class");
System.out.println("value:" + x); //Compile error
System.out.println("value:" + y); //Ok
}
}
InnerMemberClass objInner = new InnerMemberClass();
objInner.display();
}
}
You can declare an inner class within the body of a method without naming the class. It is known as anonymous class.
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.
They are typically declared as either subclasses of an existing class, or as implementations of some interface.No constructor can be provided for them.
class Car {
public void drive() {
System.out.println("car-drive");
}
}
public class Demo {
public static void main(String[] args) {
Car bmw = new Car() {
public void drive() {
System.out.println("BMW Car-drive");
}
};
bmw.drive();
}
}
Output:
BMW Car-drive
In the above code an instance of an anonymous class is created. Here we have created an instance of a child class of the Car class, actually an instance of an anonymous child class of the Car class.
So by creating an anonymous inner class, we can override one or more methods of a parent class.In the above example, Car class is parent class and 'drive' is the method being overriden.
But all this we coud have done by just creating a parent class and having it extend and override the method.Then you may ask what is the need of creating an anonymous inner class when just a separate class would have done the same stuff?
It is lot quicker to create an anonymous inner class rather than create a new separate child class.Especially, it is useful when you only need to override few methods in parent class rather than deal with overhead of creating an entire class.
Nested classes enable you to logically group classes that are only used in one place, increase the use of encapsulation, and create more readable and maintainable code. Local classes, anonymous classes also impart these advantages; however, they are intended to be used for more specific situations: