Lesson 11,Nested Classes and Interfaces
嵌套类和嵌套接口
LiFan(李凡)
Chengdu University of Information Technology
The Department Of Computer Science
2005
Nested Types (嵌套类型 )
? 嵌套类型 (Nested Types)指声明在其它类或
接口中的类或接口
? Java语言在 1.2版本以后才提供对嵌套类型的
支持
? 提供对嵌套类型的支持有以下目的,
(1) 使类型 (类或接口 )构成不同的逻辑分组
(2) 以简单有效的方式将逻辑上相关的对象
组织在一起
嵌套类型的分类
? 嵌套类型包括 嵌套类 和 嵌套接口
? 根据嵌套类型声明的位置,可以分为 成
员类型 和 局部类型
? 与嵌套类型相对,包含嵌套类型的类型
称为 封装类 (Enclosing Class)
Member Types (成员类型 )
? 成员类型 (Member Types)指定义在其
它类型中,与其它类型的域和方法同级
的类型
? 成员类型分为 成员类 (Member Classes)
和 成员接口 (Member Interfaces)
? 成员类分为 静态成员类 和 非静态成员类
? 成员接口只能是 静态成员接口
Static Member Classes (静态成员类 )
? 静态成员类可以声明在类或接口中,与类的
静态域和静态方法相似,被 static关键字修饰
? 除了类名表达方式外,静态成员类与一般的
非嵌套类相同,可以被 final或 abstract修饰
? 静态成员类与其封装类型一般具有紧密的逻
辑相关性
? 静态成员类中能直接访问其封装类中静态成
员,但不能访问非静态成员
package bank;
public class BankAccount{
private long number;
private long balance;
public static class Permissions{
public boolean canDeposite,
canWithdraw,
canClose;
}
……
}
Static Member Classes (静态成员类 )
? 可以使用与类的静态成员相同的访问控制修
饰符来控制对静态成员类的访问
? 静态成员类的类名表达有两种方式,
(1) <封装类型名 >.<静态成员类类名 >
(2) 当封装类在包中时,可以导入静态成员
类,直接使用类名
? 静态成员类的引用类型变量的声明和静态成
员类的对象创建与一般非嵌套类相同
import bank.BankAccount;
……
BankAccount.Permissions perms=new BankAccount.Permissions();
……
import bank.BankAccount.Permissions;
……
Permissions perms=new Permissions();
……
Non-static Member Classes (非静态成员类 )
? 非静态成员类只能声明在类中
? 非静态成员类的对象总是与其封装类的对象
相关联,在语义上,没有封装类的对象就不
能存在非静态成员类的对象
? 非静态成员类中可以直接访问其封装类的所
有成员,除非被非静态成员类中声明的同名
成员隐藏
? 非静态成员类中不能包含 static的成员
public class BankAccount{
private long number;
private long balance;
private Action lastAct;
public class Action{
private String act;
private long amount;
Action(String act,long amount){
this.act=act;
this.amount=amount;
}
public String toString(){
return number+,:,+act+,,+amount;
}
}
public void deposite(long amount){
balance+=amount;
lastAct=new Action(“deposite”,amount);
}
……
}
Non-static Member Classes (非静态成员类 )
? 非静态成员类中的 this引用只能访问非静态
成员类实例本身,要访问其封装类实例必须
使用以下语法格式,<封装类类名 >.this
例如,BankAccount.this.balance
? 非静态成员类的类名表达方式与静态成员类
相同,但创建对象要按照以下语法格式,
<封装类对象引用 >.new <非静态成员类构造函数 >
import bank.BankAccount;
import bank.BankAccount.Action;
……
BankAccount account=new BankAccount();
Action act=account.new Action();
……
Nested Interfaces (嵌套接口 )
? 嵌套接口可以声明在类或接口中
? 嵌套接口只能作为封装类或封装接口的
静态成员,通常 static修饰符被忽略
? 在面向接口的设计原则中,嵌套接口通
常作为其封装类或封装接口中方法的返
回类型
Local Types (局部类型 )
? 局部类型 (Local Types)指定义在其它类的方
法或初始化块中的类型
? 局部类型只能是类不能是接口,声明在静态
方法或静态初始化块中的局部类称为 静态局
部类,声明在非静态方法或非静态初始化块
中的局部类称为 非静态局部类
? 非静态局部类和非静态成员类又统称为 内部
类 (Inner Classes)
Local Types (局部类型 )
? 局部类中不能包含静态成员
? 局部类只能使用 final或 abstract关键字修饰,
不能使用 public或 static修饰
? 非静态局部类可以使用与非静态成员类相同
的方式访问其封装类的实例
? 非静态局部类中可以直接访问其封装方法的
局部变量或参数变量,但局部变量或参数变
量必须声明为 final
Local Types (局部类型 )
? 局部类的域可以隐藏其封装方法中的同名局
部变量或参数变量,其封装方法中的同名局
部变量或参数变量一旦被隐藏则无法访问
? 局部类只能在其封装方法或封装块中使用
package java.util.Iterator;
public interface Iterator{
boolean hasNext();
Object next() throws NoSuchElementException;
void remove() throws NoSuchElementException;
}
public static Iterator walkThrough(final Object[] objs){
class Iter implements java.util.Iterator{
private int pos=0;
public boolean hasNext(){
return (pos<objs.length);
}
public Object next(){
if(pos>=objs.length) throw new NoSuchElementException();
return objs[pos++];
}
public void remove(){…}
}
return new Iter();
}
Anonymous Classes (匿名类 )
? 匿名类是一种特殊的局部类
? 匿名类通常作为抽象类或接口的实现类使用
? 匿名类不能定义自己的构造函数,只能使用
父类或默认的构造函数
? 匿名类对象的创建的同时也提供了对接口或
抽象类的实现
public static Iterator walkThrough(final Object[] objs){
return new Iterator(){
private int pos=0;
public boolean hasNext(){
return (pos<objs.length);
}
public Object next(){
if(pos>=objs.length) throw new NoSuchElementException();
return objs[pos++];
}
public void remove(){…}
}
}
package java.util.Iterator;
public interface Iterator{
boolean hasNext();
Object next() throws NoSuchElementException;
void remove() throws NoSuchElementException;
}
Inheritanting Nested Types
? 继承静态成员类或实现成员接口遵循一般的
继承类或实现接口的规则
? 内部类的子类必须与被继承的内部类的封装
类的实例关联
? 内部类的子类不一定也是内部类
class Outer{
class Inner{}
}
class ExtendedOuter extends Outer{
class ExtendedInner extends Inner{}
}
Outer outerRef=new ExtendedOuter();
Outer.Inner innerRef=outerRef.new ExtendedInner();
class Unrelated extends Outer.Inner{
Unrelated(Outer ref){
ref.super();
}
}
Outer outerRef=new Outer();
Unrelated ref=outerRef.new Unrelated();
错误
Unrelated ref=new Unrealted(outerRef);
abstract class Device{
abstract class Port{
……
}
}
class Printer extends Device{
class SerialPort extends Port{
public String toString(){
return,Printer.Port”;
}
}
public Port serial=new SerialPort();
}
class HighSpeedPrinter extends Printer{
class SerialPort extends Printer.Port{
public String toString(){
return,HighSpeedPrinter.Port”;
}
}
}
HighSpeedPrinter printer=new HighSpeedPrinter();
System.out.println(printer.serial);
Assignments (作业 )
? 重新设计前面例子中的类 Printer和类
HighSpeedPrinter,使 HighSpeedPrinter
类对象中继承父类的域 serial为
HighSpeedPrinter.SerialPort类的实例