Inner Classes
Inner Classes
Agenda
1. Introduction.
2. Normal or Regular inner classes
o Accessing inner class code from
a class
o Anonymous Inner Class that
implements an interface
o Anonymous Inner Class that define
inside method arguments
o Difference between general class
7. Conclusions
Introduction
Sometimes we can declare a class inside
another class such type of classes are
called inner classes.
Diagram:
Sun people introduced inner classes in
1.1 version as part of "EventHandling"
to resolve GUI bugs.
But because of powerful features and
benefits of inner classes slowly the
programmers starts using in regular
coding also.
Without existing one type of object if
there is no chance of existing another
type of object then we should go for
inner classes.
Example:
Example1:
Example 2:
Example:
Example 3:
Without existing Map object there is no
chance of existing Entry object hence Entry
interface is define inside Map interface.
Map is a collection of key-value pairs, each
key-value pair is called an Entry.
Example:
Diagram:
Note : Without existing Outer class Object
there is no chance of existing Inner class
Object.
Note: The relationship between outer class
and inner class is not IS-A relationship
and it is Has-A relationship.
Based on the purpose and position of
declaration all inner classes are divided into 4
types.
They are:
1. Normal or Regular inner classes
2. Method Local inner classes
3. Anonymous inner classes
4. Static nested classes.
1. Normal (or) Regular inner class:
If we are declaring any named class inside
another class directly without static modifier
such type of inner classes are called normal
or regular inner classes.
Example:
class Outer
{
class Inner
{
}
}
Output:
Example:
class Outer
{
class Inner
{
}
public static void main(String[]
args)
{
System.out.println("outer
class main method");
}
}
Output:
System.out.println("inner class
main method");
}
}
}
Output:
E:\scjp>javac Outer.java
Outer.java:5: inner classes cannot
have static declarations
public static void
main(String[] args)
Example:
class Outer
{
class Inner
{
public void methodOne(){
System.out.println("inner class
method");
}
}
public static void main(String[]
args)
{
}
}
Example:
class Outer
{
class Inner
{
public void methodOne()
{
System.out.println("inner class
method");
}
}
public void methodTwo()
{
Inner i=new Inner();
i.methodOne();
}
public static void main(String[]
args)
{
Outer o=new Outer();
o.methodTwo();
}
}
Output:
E:\scjp>javac Outer.java
E:\scjp>java Outer
Inner class method
Example:
class Outer
{
class Inner
{
public void methodOne()
{
System.out.println("inner class
method");
}
}
}
class Test
{
public static void main(String[]
args)
{
new Outer().new
Inner().methodOne();
}
}
Output:
Inner class method
System.out.println(x);//10
System.out.println(y);//20
}
}
public static void main(String[]
args)
{
new Outer().new
Inner().methodOne();
}
}
System.out.println(x);//1000
System.out.println(this.x);//100
System.out.println(Outer.this.x);//10
}
}
public static void main(String[]
args)
{
new Outer().new
Inner().methodOne();
}
}
Diagram:
Nesting of Inner classes :
Diagram:
Method local inner classes:
Sometimes we can declare a class inside
a method such type of inner classes are
called method local inner classes.
The main objective of method local
inner class is to define method specific
repeatedly required functionality.
Method Local inner classes are best
suitable to meet nested method
requirement.
We can access method local inner class
only within the method where we
declared it. That is from outside of the
method we can't access. As the scope of
method local inner classes is very less,
this type of inner classes are most rarely
used type of inner classes.
Example:
class Test
{
public void methodOne()
{
class Inner
{
public void sum(int
i,int j)
{
System.out.println("The sum:"+
(i+j));
}
}
Inner i=new Inner();
i.sum(10,20);
;;;;;;;;;;;;;
i.sum(100,200);
;;;;;;;;;;;;;;;
i.sum(1000,2000);
;;;;;;;;;;;;;;;;;
}
public static void main(String[]
args)
{
new Test().methodOne();
}
}
Output:
The sum: 30
The sum: 300
The sum: 3000
System.out.println(x);//10
System.out.println(y);//20
}
}
Inner i=new Inner();
i.methodTwo();
}
public static void main(String[]
args)
{
new Test().methodOne();
}
}
System.out.println(x);//10
System.out.println(y); //C.E:
local variable y
is
accessed from within inner class;
needs
to be declared final.
}
}
Inner i=new Inner();
i.methodTwo();
}
public static void main(String[]
args)
{
new Test().methodOne();
}
}
System.out.println(i);
System.out.println(j); //-->line
1
System.out.println(k);
System.out.println(l);
}
}
Inner i=new Inner();
i.methodTwo();
}
public static void main(String[]
args)
{
new Test().methodOne();
}
}
System.out.println("salty");
}
};
p.taste();//salty
PopCorn p1=new PopCorn()
p1.taste();//spicy
}
}
Analysis:
1. PopCorn p=new PopCorn();
We are just creating a PopCorn object.
2. PopCorn p=new PopCorn()
3. {
4. };
5. We are creating child class without
name for the PopCorn class and for that
child class we are creating an object
with Parent PopCorn reference.
6. PopCorn p=new PopCorn()
7. {
8. public void taste()
9. {
10.
System.out.println("salty");
11. }
12. };
13.
1. We are creating child class for PopCorn
without name.
2. We are overriding taste() method.
3. We are creating object for that child
class with parent reference.
Note: Inside Anonymous inner classes we
can take or declare new methods but outside
of anonymous inner classes we can't call
these methods directly because we are
depending on parent reference.[parent
reference can be used to hold child class
object but by using that reference we can't
call child specific methods]. These methods
just for internal purpose only.
Example 1:
class PopCorn
{
public void taste()
{
System.out.println("spicy");
}
}
class Test
{
public static void main(String[]
args)
{
PopCorn p=new PopCorn()
{
public void taste()
{
methodOne();//valid call(internal
purpose)
System.out.println("salty");
}
public void methodOne()
{
System.out.println("child
specific method");
}
};
//p.methodOne();//here we
can not call(outside inner class)
p.taste();//salty
PopCorn p1=new PopCorn();
p1.taste();//spicy
}
}
Output:
Child specific method
Salty
Spicy
Example 2:
class Test
{
public static void main(String[]
args)
{
Thread t=new Thread()
{
public void run()
{
for(int
i=0;i<10;i++)
{
System.out.println("child
thread");
}
}
};
t.start();
for(int i=0;i<10;i++)
{
System.out.println("main
thread");
}
}
}
Example:
class InnerClassesDemo
{
public static void main(String[]
args)
{
Runnable r=new
Runnable() //here we are not creating
for
Runnable
interface, we are creating
implements
class object.
{
public void run()
{
for(int
i=0;i<10;i++)
{
System.out.println("Child
thread");
}
}
};
Thread t=new Thread(r);
t.start();
for(int i=0;i<10;i++)
{
System.out.println("Main
thread");
}
}
}
System.out.println("child
thread");
}
}
}).start();
for(int i=0;i<10;i++)
{
System.out.println("main
thread");
}
}
}
Output:
f.addWindowListener(new
WindowAdaptor(){
public void
windowClosing(WindowEvent e) {
System.exit(0);
}
});
---------------------
}
----------------
b2.addActionListener(new
ActionListener() {
public void
actionPerformed(ActionEvent e) {
//perform b2 specific functionality
}
});
---------
}
System.out.println("nested class
method");
}
}
public static void main(String[]
args)
{
Test.Nested t=new
Test.Nested();
t.methodOne();
}
}
System.out.println("nested class
main method");
}
}
public static void main(String[]
args)
{
System.out.println("outer
class main method");
}
}
Output:
E:\SCJP>javac Test.java
E:\SCJP>java Test
Outer class main method
E:\SCJP>java Test$Nested
Nested class main method
System.out.println(x);//C.E:non-
static variable x
cannot
be referenced from a static context
System.out.println(y);
}
}
}
}
3. interface inside a interface :
We can declare an interface inside another
interface.
interface Map {
interface Entry {
public Object getKey();
public Object getValue();
public Object getValue(Object
new );
}
}
Nested interfaces are always public,static
whether we are declaring or not. Hence we
can implements inner inteface directly with
out implementing outer interface.
interface Outer {
public void methodOne();
interface Inner {
public void methodTwo();
}
}
}
i.e., Both Outer and Inner interfaces we can
implement independently.
4. class inside a interface :
We can declare a class inside interface. If a
class functionality is closely associated with
the use interface then it is highly
recommended to declare class inside
interface
Example:
interface EmailServer {
public void sendEmail(EmailDetails
e);
class EmailDetails {
String from;
String to;
String subject;
}
}
In the above example Emaildetails
functionality is required for EmailService and
we are not using anyware else . Hence we
can declare EmailDetails class inside
EmailService interface .
interface Vehicle {
public int getNoOfWheels();
class Test {
public static void main(String
args[]) {
Bus b=new Bus();
System.out.println(b.getNoOfWheels());
Vehicle.DefaultVehicle d=new
Vehicle.DefaultVehicle();
System.out.println(d.getNoOfWheels());
}
}
In the above example DefaultVehicle in the
default implementation of Vehicle interface
where as Bus customized implementation of
Vehicle interface.
The class which is declared inside interface is
always static ,hence we can create object
directly without having outer interface type
object.
Conclusions :
1. We can declare anything inside any
thing with respect to classes and
interfaces.
BACK