一、Java中引入内部类的原因:
(1)、完善继承机制。
Java仅支持单继承,一个类不能同时继承两个类。Java给出的解决多继承的解决方案是: 接口+内部类。
当我们自己设计时,一般利用接口代替要继承的类,当需要继承两个父类时,就采用内部类实现。
(2)、实现事件驱动系统
在swing中,当需要添加事件监听者时,一般使用匿名内部类解决。
(3)、内部类一旦创建,就自动拥有一个它的外部类的引用。有了这个引用,内部类可以访问外部类中的所有成员和方法,包括private的。
《Java编程思想》:
使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。
1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建内部类对象的时刻并不依赖于外围类对象的创建。
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。
二、成员内部类
public class Outer {
public int id;
private String name;
public void print(){
System.out.println(1);
}
public class Inner{
Inner(){
id =1;
name = "hah";
}
public void print(){
System.out.println(name);
}
}
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个得到内部类的实例
Outer.Inner inner = outer.new Inner();
inner.print();
outer.print();
}
}
//输出:
//hah
//1
内部类是个编译时的概念,一旦编译成功后,它就与外围类属于两个完全不同的类(当然他们之间还是有联系的)。当需要一个内部类实例时,首先必须要有它外部类的实例,通过该外部类实例创建内部类。下面是更好的创建方法:
public class Outer1 {
public class Inner{
public void print(){
System.out.println("hh");
}
public Outer1 getOuter(){
return Outer1.this;
}
}
public Inner getInner(){
return new Inner();
}
public static void main(String[] args) {
Outer1 outer = new Outer1();
Outer1.Inner inner = outer.getInner();
inner.print();
Outer1 newOuter = inner.getOuter();
//返回true 说明newOuter和outer返回同一个外部类对象
System.out.println(newOuter==outer);
}
}
注意:内部类可以直接访问外部类的元素,但是外部类不可以直接访问内部类的元素
三、成员内部类
内部类定义在外部类的方法中,这种内部类的生命周期和该方法相同,方法调用结束,则类对象失效。
class Outter {
private int age = 12;
public void Print(final int x) { //这里局部变量x必须设置为final类型!
class Inner {
public void inPrint() {
System.out.println(x);
System.out.println(age);
}
}
new Inner().inPrint();
}
}
public class test1 {
public static void main(String[] args) {
Outter out = new Outter();
out.Print(10);
}
}
如果想往含有内部类的外部方法中传入参数,参数类型必须是 final声明的。
四、静态内部类
public class Outer2 {
private static int id = 1;
private int num = 1;
static class Inner{
public void print(){
//只能访问外部类中的静态变量
System.out.println(id);
}
}
public static void main(String[] args) {
Outer2.Inner inner = new Outer2.Inner();
inner.print();
}
}
静态内部类只能访问外部类的static 方法、成员。 在得到静态内部类实例时,也可以由外部类直接得到。
五、匿名内部类
多用于swing中的事件驱动程序。