Вы находитесь на странице: 1из 15

SkillSoft Learning Object Page 1 of 15

Java inner classes

Learning objective

After completing this topic, you should be able to declare and instantiate Java's inner classes for a given
scenario.

1. Basic inner classes

A class that's defined within another class is known as a nested, or inner, class.

You can define nested - or inner - classes to implement a type of aggregation relationship between
objects.

Aggregation is a strong form of relationship, also called composition, where one object's lifetime is entirely
associated with an enveloping object. The outer object is said to have a "has-a" relationship with the inner
object.

Inner classes help implement one form of the "has-a" relationship - where the inner classes are also
defined within the outer class.

Nested classes allow one class - the outer class - to make explicit use of another class without having to
change its inheritance hierarchy.

A good example of this is event handling for GUIs. You can ask an inner class to extend the appropriate
event handler class while the main, outer, class extends from its own hierarchy. This greatly simplifies
event handling.

You declare an inner class in the same way as an ordinary class - except that the inner class occurs
between the opening and closing braces of the outer class.

The inner class can inherit from any superclass or implement any interface, regardless of the outer
classes' inheritance hierarchy.

public class OuterClass {

private int i = 100;


InnerClass in;

public OuterClass(int i) {
this.i = i;
in = new InnerClass(++i);
}

class InnerClass {
int y;

public InnerClass(int startVal) {


System.out.println(i);
y = startVal;
}
}
}

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 2 of 15

Strictly speaking, nested classes are static classes, while inner classes are always non-static.

An inner class may not have static members or static initializers, aside from constants.

public class OuterClass {

private int i = 100;


InnerClass in;

public OuterClass(int i) {
this.i = i;
in = new InnerClass(++i);
}

class InnerClass {
int y;

public InnerClass(int startVal) {


System.out.println(i);
y = startVal;
}
}
}

Question

Suppose you needed to declare an inner class to implement a type of aggregation relationship
between objects.

Identify the code to declare the inner class.

public class Vehicle {

private int i = 100;


Motorcar in;

public Vehicle(int i) {
this.i = i;
in = new Motorcar(++i);
}

class Motorcar {
int y;

public Motorcar(int startVal) {


System.out.println(i);
y = startVal;
}
}
}

Options:

1. class Motorcar
2. public class Vehicle

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 3 of 15

3. public Motorcar(int startVal)


4. public Vehicle(int i)

Answer

You type class Motorcar to declare the inner class.

Option 1 is correct. You declare an inner class in the same way as an ordinary class, except
that the inner class occurs between the opening and closing braces of the outer class.

Option 2 is incorrect. Although the class declaration is syntactically correct, it is used to declare
the outer class.

Option 3 is incorrect. This is an inner class method declaration, not an inner class declaration.

Option 4 is incorrect. This is an outer class method declaration, not an inner class declaration.

You need to have an existing instance of an outer class before you can instantiate its inner class. In the
example, the inner class instance is created in the outer class constructor, guaranteeing that the outer
instance exists.

Creating an inner object in an outer class constructor is useful because it ensures that the lifetime of the
inner object matches that of the outer object.

public class OuterClass {

private int i = 100;


InnerClass in;

public OuterClass(int i) {
this.i = i;
in = new InnerClass(++i);
}

class InnerClass {
int y;

public InnerClass(int startVal) {


System.out.println(i);
y = startVal;
}
}
}

Once you have created an inner object, it implicitly references the instance of the outer class to which it
belongs.

All members of the outer object are directly and automatically accessible to the inner object - including
private members. In the example, the inner class automatically has access to the outer class's instance
variable, i.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 4 of 15

public class OuterClass {

private int i = 100;


InnerClass in;

public OuterClass(int i) {
this.i = i;
in = new InnerClass(++i);
}

class InnerClass {
int y;

public InnerClass(int startVal) {


System.out.println(i);
y = startVal;
}
}
}

You can create an instance of an inner class from external classes or from a static method, such as the
outer class's main method.

When you try to instantiate an inner class from an external class, you still need to instantiate the
corresponding outer class.

You can do so in one line, by creating both the outer and inner classes together in two successive new
statements.

The second line of code illustrates how to reference a method in the inner class.

// instantiating an inner class from an external class


OuterClass.InnerClass in = new OuterClass().new InnerClass();

// referencing a method in the inner class


in.InnerMethod();

Question

Suppose you want to instantiate an object, called temp, of an inner class named ToFaren,
from within an external class. The outer class is called Conv and an instance of it is
unavailable.

Complete the code to do this.

Conv.ToFaren temp = new Conv().MISSING CODE;

Answer

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 5 of 15

To complete the code to instantiate the object you type

new ToFaren()

Instead of creating both the inner and outer classes in one line, you can instantiate each class in a
separate statement.

OuterClass out = new OuterClass();


OuterClass.InnerClass in = out.new InnerClass();

The fully qualified reference type name of the new inner object is OuterClass.InnerClass.

You need to use the fully qualified name of an inner class only if you are creating an instance from
outside an instance of the outer class - otherwise, its name is simply InnerClass.

OuterClass out = new OuterClass();


OuterClass.InnerClass in = out.new InnerClass();

When you compile the code, the class file for the inner class will automatically be called
OuterClass$InnerClass.class, rather than OuterClass.InnerClass.class.

This prevents any confusion when saving files between inner classes and package members.

OuterClass out = new OuterClass();


OuterClass.InnerClass in = out.new InnerClass();

Question

Why would you want to declare an inner class?

Options:

1. To ensure that the lifetime of the inner object matches that of the outer object
2. To gain access to the private members of the outer class
3. To implement a "has-a" relationship between two classes
4. To simplify event handling

Answer

You declare an inner class to help implement strong, "has-a" relationships between classes and
simplify event handling. You implicitly gain access to private members of the outer class.

Option 1 is incorrect. Creating an inner object in an outer class constructor ensures that the
lifetime of the inner object matches that of the outer object.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 6 of 15

Option 2 is correct. An inner class has implicit access to private members of its outer class and
can refer to them directly.

Option 3 is correct. Outer and inner classes have a "has-a" relationship. When two classes are
bound very tightly, and when the lifetime of one object is entirely contained within the lifetime of
its enclosing object, then inner classes are one appropriate solution.

Option 4 is correct. Event handling adapters appear in strict hierarchies. In order to promote
simplicity of design, you can use inner classes and avoid altering the outer classes inheritance
hierarchy.

2. Static inner classes

One of the main differences between inner classes and outer classes is that you can declare inner
classes to be static.

Note

Static inner classes are also known as nested classes, although the terms are loosely defined.

Static inner objects operate in strong association with the outer class, but are not bound to any one
instance of the outer class. They are usually supporting classes that provide additional useful functionality
directly to the class.

You use the static keyword to declare the class as static.

public class Outerclass {


static class InnerClass {
}

Like static methods and variables, static inner classes can be used even if no instance of their enclosing
class exists.

So static inner class objects can be created without creating an instance of the outer class.

For example, two instances of the static class InnerClass are created in the main method of
Outerclass.

public class Outerclass {


static class InnerClass {
}
public static void main (String[] args) {
InnerClass c = new InnerClass();
InnerClass c1 = new InnerClass();
}
}

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 7 of 15

To create an instance of a static inner class from outside of an outer class, you must use the class name
to reference it.

You should note particularly that only one new statement is required.

OuterClass.InnerClass myObj = new OuterClass.InnerClass();

Question

Suppose you want to declare a static inner class called innerVehicle.

Complete the code to do this.

public class outerVehicle {


MISSING CODE {
}

Answer

You type static class innerVehicle to declare the static inner class.

You can instantiate a static inner class as many times as you like.

This characteristic of static inner classes differentiates them from static variables because a class has
only a single copy of each of its static variables.

public class Outerclass {


static class InnerClass {
}
public static void main (String[] args) {
InnerClass c = new InnerClass();
InnerClass c1 = new InnerClass();
}
}

There are limits on the types of outer class variables that a static inner class can access directly.

public class Outerclass {


static int j;
int k;
static class InnerClass {
void aMethod() {
int l = j;
int m = k;
}

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 8 of 15

}
}

In this code, the inner class InnerClass attempts to access two variables declared in the outer class. The
relevant code is

l = j;
m = k;

l = j;
Static inner class methods can directly access all the static variables of the outer class, because
these variables are not associated with any class instance.

So InnerClass can access the variable j.


m = k;
Because a static inner object is not associated with an outer object, methods contained in a
static inner class do not have direct access to the instance variables of the outer class.

So InnerClass cannot access the variable k.

Question

Given the code, which of the three lines of code would compile without error?

public class Vehicle {


static int f;
float a;
int d;
static class Motorbike {
void aMethod() {
int l = f;
int e = d;
float b = a;
}
}
}

Options:

1. float b = a;
2. int e = d;
3. int l = f;

Answer

The line of code int l = f; will not cause an error.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 9 of 15

Option 1 is incorrect. Static inner classes can access only variables declared as static in the
outer class.

Option 2 is incorrect. Because the inner class is static, you can only access static variables of
the outer class.

Option 3 is correct. There are limits on the types of outer class variables a static inner class can
access directly. They need to be of type static.

Question

Suppose you want to create an instance of a static inner class called Motorbike from outside
an outer class.

Complete the code to do this.

Vehicle.Motorbike myObj = MISSING CODE.Motorbike();

Answer

You type new Vehicle to create an instance of a static inner class from outside an outer
class.

3. Local inner classes

A local inner class is defined within a method.

When you declare and instantiate a local inner class within a method, the object can exist after the
method has been invoked and has exited.

However, any variables or arguments local to this method no longer exist at this point, so they cannot be
accessed by the local inner class.

You need to declare a method's local variables and parameters as final if you want them to be accessible
by local inner classes within the method. The value of final variables and parameters are copied to each
local inner class instance.

This way, the method's variables become accessible even once the method has exited.

A good reason to declare an inner class as local is that the inner class is completely hidden from outside
code.

The only method that is aware of the local class is the method in which it is instantiated.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 10 of 15

You do not declare local classes with an access specifier - public or private.

public class OuterClass2 {

public void aMethod(final int i) {


class InnerClass {
int y;

public InnerClass(int startVal) {


System.out.println(i);
y = startVal;
}
}

InnerClass in = new InnerClass(20);


}

public static void main(String[] args){


new OuterClass2().aMethod(10);
}
}

The scope of the local class is limited to the block in which it is declared.

Question

Suppose you have defined a local inner class within a method named userDetails. You want
the inner class to access an integer variable idNo that belongs to userDetails.

To enable the local inner class to access the variable idNo, what should you declare it as?

Options:

1. Final
2. Private
3. Public

Answer

To enable the local inner class to access the variable idNo, you declare it as final.

Option 1 is correct. Only variables or parameters declared as final can be fixed. Because inner
object instances can exist beyond the method's life-time, they can access only fixed values.
The value of final variables and parameters are copied to each local inner class instance.

Option 2 is incorrect. Local variables cannot be declared private - they are implicitly restricted to
the method.

Option 3 is incorrect. Local variables cannot be declared public. All local variables of the
containing method of a local inner class are available to that class. But they must be made final
so that their value is fixed and can be copied to the instance of the inner class.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 11 of 15

Question

Suppose you want to instantiate a local inner class called InnerVehicle.

Identify the correct statement to do this.

public class OuterVehicle {

public void aMethod(final int i) {


class InnerVehicle {
int y;

public InnerVehicle(int startVal) {


System.out.println(i);
y = startVal;
}
}

MISSING CODE;
}

public static void main(String[] args){


new OuterVehicle().aMethod(10);
}
}

Options:

1. InnerVehicle inVec = new InnerVehicle();


2. class InnerVehicle
3. OuterVehicle.InnerVehicle in = new OuterVehicle().new
InnerVehicle();

Answer

You use InnerVehicle inVec = new InnerVehicle(); to instantiate the local inner
class.

Option 1 is correct. When you declare and instantiate a local inner class within a method, the
object can exist after the method has been invoked and has exited.The only method that is
aware of the local class is the method in which it is instantiated.

Option 2 is incorrect. This is the code you use to declare a local inner class within a method of
an outer class. When you declare a local inner class you do not declare it with an access
specifier.

Option 3 is incorrect. This code is used to instantiate a basic inner class. You can create an
instance of an inner class from external classes or from a static method, such as the outer
class's main method. When you try to instantiate an inner class from an external class, you still
need to instantiate the corresponding outer class.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 12 of 15

4. Anonymous inner classes

An anonymous inner class is an inner class that is declared within a method call and not assigned a
name.

Instances of anonymous classes are always created and used in the same place that the class is defined,
so you never need to use a class name to declare a reference type or create an instance of it.

Because anonymous classes don't have names, they can't have constructors.

An anonymous class can be a subclass, or it can implement an interface.

However, it can't be a subclass that implements an interface.

In Java, anonymous classes are primarily used for event handling. The typical use of an anonymous
class is the event listener. An event listener is a class instance that is registered and then waits for and
handles graphic user interface (GUI) events such as clicking a button or exiting a window.

The anonymous class is declared within the argument list to the appropriate listener registration method
call. In the example, the anonymous inner class is declared in the call to addWindowListener.

import java.awt.*;
import java.awt.event.*;
public class ExitFrame extends Frame {
ExitFrame (String label) {
super (label) ;
}
public static void main (String [] args) {
ExitFrame f = new ExitFrame ("Click the x to exit");
f.setBounds (25, 25, 250, 250);
f.setVisible (true);
// Defines an anonymous inner class
// to handle window exit events
f.addWindowListener (new WindowAdapter () {
public void windowClosing (WindowEvent e) {
System.exit (0);
}
});
}
}

// Declaring event handlers as anonymous inner classes


addXXXListener (new XXXAdapter () {
// code for anonymous class
});

Note

Take particular note of the opening and ending braces and parentheses. These are quite
unusual - the class definition and method call always end with the string "});" - which makes
sense when you read the syntax carefully.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 13 of 15

In the code, there is no class name - instead, there is just a superclass name, WindowAdapter.

WindowAdapter is an abstract class that specifies the methods needed to deal with window events.

Using an existing class name tells Java that you want to create a new anonymous class. It also indicates
that you want the class to subclass the WindowAdapter class without using the extends keyword.

import java.awt.*;
import java.awt.event.*;
public class ExitFrame extends Frame {
ExitFrame (String label) {
super (label) ;
}
public static void main (String [] args) {
ExitFrame f = new ExitFrame ("Click the x to exit");
f.setBounds (25, 25, 250, 250);
f.setVisible (true);
// Defines an anonymous inner class
// to handle window exit events
f.addWindowListener (new WindowAdapter () {
public void windowClosing (WindowEvent e) {
System.exit (0);
}
});
}
}

Note

You can create an anonymous inner class that implements an interface by using an interface
name instead of a superclass name.

The anonymous inner class is declared and instantiated in the same location within the method call, using
the new keyword.

You can create instances of the anonymous class only once, at the same location as you define it.

import java.awt.*;
import java.awt.event.*;
public class ExitFrame extends Frame {
ExitFrame (String label) {
super (label) ;
}
public static void main (String [] args) {
ExitFrame f = new ExitFrame ("Click the x to exit");
f.setBounds (25, 25, 250, 250);
f.setVisible (true);
// Defines an anonymous inner class
// to handle window exit events
f.addWindowListener (new WindowAdapter () {
public void windowClosing (WindowEvent e) {

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 14 of 15

System.exit (0);
}
});
}
}

Anonymous inner classes can make your code difficult to read, so they should be used only where their
purpose is obvious and where the inner class is small.

Question

Suppose you wanted to create a new object of a class that implements the ActionListener
interface - without giving the class name.

Complete the code to do this.

public void calc(final int numCar)


{
ActionListener Vec = MISSING CODE()
{
// ...
}
// ...
}

Answer

You type new ActionListener to create the object anonymously.

Summary

Inner classes offer a way to implement aggregation, or "has-a", relationships between objects. They help
simplify event handling and enforce strong association semantics on classes. An inner class is defined in
the context of another class. Before you instantiate a non-static inner class, you must instantiate its outer
class.

You can instantiate a static inner class without instantiating its outer class. Static inner classes do not
have direct access to their outer class's instance variables.

An inner class that's defined within a method is called a local inner class. It can have access only to final
local variables and parameters.

An anonymous inner class is a class that is declared and instantiated in a single step, and is not assigned
a name. They are typically used to handle events.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016
SkillSoft Learning Object Page 15 of 15

Copyright 2008 SkillSoft. All rights reserved.


SkillSoft and the SkillSoft logo are trademarks or registered trademarks
of SkillSoft in the United States and certain other countries.
All other logos or trademarks are the property of their respective owners.

https://xlibrary.skillport.com/javalibrary/cbtlib/252347/252397/eng/thin/transcript.html 6/15/2016

Вам также может понравиться