内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类。
为什么需要内部类?
典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是:
每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
/**
* 外部类
*/
public class Outer {
private String param = "outer param";
public void print(){
System.out.println("Outer >> print()");
}
public Say sayHello(String s){
/**
* 局部内部类:指内部类定义在方法和作用域内。
*/
class SayHello implements Say{
private String text;
private SayHello(String text){
this.text = text;
}
@Override
public void say() {
System.out.println("I say " + this.text);
}
}
return new SayHello(s);
}
/**
* 当所在方法的形参需要被匿名内部类使用时,该形参必须为final。
*/
public Say sayHello2(final String s){
//匿名内部类
return new Say() {
@Override
public void say() {
System.out.println("I say " + s + " again"); //匿名内部类方法中访问所在方法的形参
}
};
}
/**
* 成员内部类:
* 作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。
* 如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类。
*/
public class Inner{
private String param = "inner param";
public void print(){
System.out.println("Outer >> Inner >> print()");
}
//在成员内部类方法中引用外部类的属性和方法
public void callOuter(){
System.out.println(Outer.this.param); //在内部类里访问外部类的成员属性
Outer.this.print(); //在内部类里访问外部类的成员方法
}
}
/**
* 嵌套内部类:修饰为static的内部类。嵌套类不能声明为private,一般声明为public,方便调用。
* 使用静态内部类的好处是加强了代码的封装性以及提高了代码的可读性。
*/
public static class NestInner{
public static void print(){
System.out.println("Outer >> NestInner >> print");
}
}
public static void main(String[] args) {
//Outer
Outer outer = new Outer();
System.out.println(outer.param);
outer.print();
Say say = outer.sayHello("love you");
say.say();
outer.sayHello2("love you").say();
//调用嵌套内部类的方法
Outer.NestInner.print();
System.out.println("\n");
//Inner
Outer.Inner inner = outer.new Inner(); //实例化成员内部类
System.out.println(inner.param);
inner.print();
inner.callOuter();
//NestInner
Outer.NestInner nestInner = new Outer.NestInner(); //实例化静态内部类
}
}