Introduction to Java programming, Part 2: Constructs for real-world applications
2011-04-27 00:00
381 查看
http://www.ibm.com/developerworks/java/tutorials/j-introtojava2/section7.html
Nested classes
In this section, learn about nested classes and where and how to use them.
Where to use nested classes
As its name suggests, a nested class is one defined within another class. Here is a nested class:
Just like member variables and methods, Java classes can also be defined at any scope including
Typically, you'll use a nested class for cases where you need a class that is tightly coupled with the class in which it is defined. A nested class has access to the private data within its enclosing class, but this carries with it some side-effects that are not obvious when you start working with nested (or inner) classes.
Back to top
Scope in nested classes
Because a nested class has scope, it is bound by the rules of scope. For example, a member variable can only be accessed through an instance of the class (an object). The same is true of a nested class.
Suppose you have the following relationship between a
Just as each
Public nested classes
Because it's
Listing 17. Creating DirectReports instances: First attempt
The code in Listing 17 doesn't work, and you're probably wondering why. The problem (and also its solution) lies with the way
The rules of scope, revisited
If you had a member variable of
To create an instance of a public nested class, you use a special version of the
Note that the syntax calls for a reference to the enclosing instance, plus a dot and the
Back to top
Static inner classes
At times you will want to create a class that is tightly coupled (conceptually) to a class, but where the rules of scope are somewhat relaxed, not requiring a reference to an enclosing instance. That's where static inner classes come into play. One common example of this is to implement a
In this case, you don't need an enclosing instance. Static inner classes act like their regular Java class counterparts, and they should really only be used when you need to couple a class tightly with its definition. Clearly, in the case of a utility class like
Back to top
Anonymous inner classes
The Java language allows you to declare classes pretty much anywhere, even in the middle of a method if necessary, and even without providing a name for the class. This is basically a compiler trick, but there are times when anonymous inner classes are extremely handy to have.
Listing 18 builds on the example in Listing 15, adding a default method for handling
Listing 18. Handling
In this example, you provide an implementation of the
Nested classes
In this section, learn about nested classes and where and how to use them.
Where to use nested classes
As its name suggests, a nested class is one defined within another class. Here is a nested class:
public class EnclosingClass { . . . public class NestedClass { . . . } } |
public,
private, or
protected. Nested classes can be useful when you want to handle internal processing within your class in an object-oriented fashion, but this functionality is limited to the class where you need it.
Typically, you'll use a nested class for cases where you need a class that is tightly coupled with the class in which it is defined. A nested class has access to the private data within its enclosing class, but this carries with it some side-effects that are not obvious when you start working with nested (or inner) classes.
Back to top
Scope in nested classes
Because a nested class has scope, it is bound by the rules of scope. For example, a member variable can only be accessed through an instance of the class (an object). The same is true of a nested class.
Suppose you have the following relationship between a
Managerand a nested class called
DirectReports, which is a collection of the
Employees that report to that
Manager:
public class Manager extends Employee { private DirectReports directReports; public Manager() { this.directReports = new DirectReports(); } . . . private class DirectReports { . . . } } |
Managerobject represents a unique human being, the
DirectReportsobject represents a collection of actual people (employees) who report to a manager.
DirectReportswill differ from one
Managerto another. In this case, it makes sense that one would only reference the
DirectReportsnested class in the context of its enclosing instance of
Manager, so I've made it
private.
Public nested classes
Because it's
private, only
Managercan create an instance of
DirectReports. But suppose you wanted to give an external entity the ability to create instances of
DirectReports? In this case, it seems like you could give the
DirectReportsclass
publicscope, and then any external code could create
DirectReportsinstances, as shown in Listing 17:
Listing 17. Creating DirectReports instances: First attempt
public class Manager extends Employee { public Manager() { } . . . private class DirectReports { . . . } } // public static void main(String[] args) { Manager.DirectReports dr = new Manager.DirectReports();// This won't work! } |
DirectReportsis defined within
Manager, and with the rules of scope.
The rules of scope, revisited
If you had a member variable of
Manager, you would expect the compiler to require you to have a reference to a
Managerobject before you could reference it, right? Well, the same applies to
DirectReports, at least as you defined it in Listing 17.
To create an instance of a public nested class, you use a special version of the
newoperator. Combined with a reference to some enclosing instance of an outer class,
newallows you to create an instance of the nested class:
public class Manager extends Employee { public Manager() { } . . . private class DirectReports { . . . } } // Meanwhile, in another method somewhere... public static void main(String[] args) { Manager manager = new Manager(); Manager.DirectReports dr = manager.new DirectReports(); } |
newkeyword, followed by the class you want to create.
Back to top
Static inner classes
At times you will want to create a class that is tightly coupled (conceptually) to a class, but where the rules of scope are somewhat relaxed, not requiring a reference to an enclosing instance. That's where static inner classes come into play. One common example of this is to implement a
Comparator, which is used to compare two instances of the same class, usually for the purpose of ordering (or sorting) the classes:
public class Manager extends Employee { . . . public static class ManagerComparator implements Comparator<Manager> { . . . } } // Meanwhile, in another method somewhere... public static void main(String[] args) { Manager.ManagerComparator mc = new Manager.ManagerComparator(); . . . } |
ManagerComparator, creating an external class is unnecessary and potentially clutters up your code base. Defining such classes as static inner classes is the way to go.
Back to top
Anonymous inner classes
The Java language allows you to declare classes pretty much anywhere, even in the middle of a method if necessary, and even without providing a name for the class. This is basically a compiler trick, but there are times when anonymous inner classes are extremely handy to have.
Listing 18 builds on the example in Listing 15, adding a default method for handling
Employeetypes that are not
StockOptionEligible:
Listing 18. Handling
Employeetypes that are not
StockOptionEligible
public static void main(String[] args) { Employee employee = new Manager();// perfectly valid handleStockOptions(employee); employee = new Employee();// not StockOptionEligible handleStockOptions(employee); } . . . private static void handleStockOptions(Employee e) { if (e instanceof StockOptionEligible) { calculateAndAwardStockOptions((StockOptionEligible)e); } else { calculateAndAwardStockOptions(new StockOptionEligible() { @Override public void awardStockOptions(int number, BigDecimal price) { log.info("Sorry, you're not StockOptionEligible!"); } }); } } . . . private static void calculateAndAwardStockOptions(StockOptionEligible soe) { BigDecimal reallyCheapPrice = BigDecimal.valueOf(0.01); int numberOfOptions = 10000; soe.processStockOptions(numberOfOptions, reallyCheapPrice); } |
StockOptionEligibleinterface by using an anonymous inner class for instances of
Employeethat do not implement that interface. Anonymous inner classes are also useful for implementing callback methods, and in event handling, too.
相关文章推荐
- Introduction to Java Programming编程题9.11<对字符串中的字符排序(支持大小写混排)>
- Website for the introduction to Matlab and Java
- A chatroom for all! Part 1 - Introduction to Node.js(转发)
- Introduction to Java Programming编程题3.28<判断两个长方形是否相交>
- Introduction to Java Programming编程题9.4<求某个字符的出现次数>
- Introduction to Java Programming-Comprehensive Version (6th Edition)
- Introduction to Java Programming编程题12.11<Remove text>
- An Introduction to Interactive Programming in Python (Part 1) - Week 0
- Website for the introduction to Matlab and Java
- An Introduction to Interactive Programming in Python (Part 2) week 6 (Classes and Tied images)
- Introduction to Java Programming编程题5.28<梅森素数>
- Introduction to Java Programming编程题12.3<ArrayIndexOutBoundsException>
- Introduction to Java Programming编程题9.2<检查子串>
- Introduction to Java Programming编程题9.5<统计字符串中数字的个数>
- Introduction to Ajax for Java Web Applications
- Introduction to Java Programming编程题9.12<变位词>
- Introduction to Java Programming编程题9.15<求字符串中大写字母的个数>
- Introduction to Java Programming编程题5.30<双素数>
- Java Thread Programming 1.1 - Introduction to Threads
- Introduction to Java Programming编程题7.6<两个矩阵相乘>