内部类的概念
在一个中又嵌套了一个类,被嵌套的类称为内部类,嵌套其他类的类称为外部类,举例:在类A的内部定义了类B,类B称为内部类,类A称为外部类。内部类可以分为四种:普通内部类,静态内部类,匿名内部类,局部内部类。下面将一一介绍:
普通内部类(成员内部类)
普通内部类是最常见的内部类之一,定义也很简单,就是直接在一个类中定义另外一个类,该内部类是作为外部类的一个成员,也可以叫做成员内部类。具体实例如下:
public class Outer {
private int num=10;
//成员内部类
public class Inter{
public void show() {
System.out.println(num);
}
}
public void method() {
Inter i=new Inter();
i.show();
}
}
成员内部类的特点
- 成员内部类对象依赖外部类对象而存在,即在创建一个成员内部类对象时,首先要创建其外部类的对象
- 成员内部类可以直接访问外部类的成员,包括私有成员,而外部类要访问内部类的成员(无论是否私有)需要通过内部类的对象来访问
- 成员内部类不能拥有静态域,但是可以访问外部类的静态域
成员内部类对象的创建
在外部类内部创建成员内部类对象:Inter i=new Inter();
在外部类外部创建成员内部类对象:Outer.Inter oi=new Outer().new Inter();
静态内部类
一个类的静态成员独立于这个类的任何一个对象存在,只要在具有访问权限的地方,就可以通过类名.静态成员名的形式来访问这个静态成员,静态内部类就是作为外部类的一个静态成员而存在,静态内部类的定义位置和成员内部类相同,都是定义在外部类的内部,作为成员的位置,静态内部类的不同之处是使用了static修饰。具体实例如下:
静态内部类的特点
由于静态成员的特点是独立于这个类的任何一个对象存在,可以通过类名.静态成员名的形式来访问这个静态成员,所以创建静态内部类对象不需要依赖其外部类对象,即静态内部类不需要外部类对象的产生就能使用
静态内部类中无法访问外部类的非静态成员,如:上图中在静态内部类中访问外部类的非静态成员num时就出现了错误。因为外部类的非静态成员是属于每一个外部类对象的,而本身静态内部类就是独立于外部类对象存在的,所以静态内部类不能访问外部类的非静态成员,而外部类依然可以访问静态内部类对象的所有访问权限的成员,这一点和成员内部类相同
静态内部类对象的创建
在外部类内部创建静态内部类对象:Inter i=new Inter();
在外部类外部创建静态内部类对象:Outer.Inter si=new Outer.Inter();
局部内部类
局部内部类是定义在外部类的成员方法内的,其提供的功能使用匿名内部类都可以实现,而本身匿名内部类可以写的更简洁,因此局部内部类使用的比较少。局部内部类具体实例如下:
public class Outer {
private int num=10;
static int age=30;
public void test() {
//局部内部类,只能在当前方法中使用
class A{
public void show() {
System.out.println("这里是局部内部类A");
}
}
A a=new A();
a.show();
}
}
局部内部类的特点
- 与局部变量类似,不在局部内部类的定义域之内,局部内部类便无法使用
- 局部内部类不可以添加访问修饰符,因为它相当于一个局部的变量,是对外部完全隐藏的,局部变量本来就是不可以使用修饰符的
- 局部内部类可以直接访问外部类的所有成员,包括私有,但是外部类访问局部类的成员需要创建对象进行访问并且必须在定义它的方法内
匿名内部类
匿名内部类与局部内部类相似,是定义在外部类的局部位置,匿名内部类正如其名字所说,没有名字,匿名内部类的本质是一个继承了某个类或者实现了某个接口的子类匿名对象。具体实例如下:
//创建一个接口
public interface jump {
void jumpping();
}
//使用匿名内部类实现接口
public class Anonym {
public void show2() {
//匿名内部类的第一种编写方式
//因为匿名内部类本质是一个对象,所以可以直接在后面调用方法
new jump() {
public void jumpping() {
System.out.println("我可以跳跃");
}
}.jumpping();
//匿名内部类的第二种编写方式
jump j=new jump() {
public void jumpping() {
System.out.println("我可以跳跃");
}
};
j.jumpping();
}
}
匿名内部类的特点
- 匿名内部类是表达式,而非常规的类,匿名内部类可以使你的代码更简洁,可以理解为其实就是一个表达式
- 匿名内部类必须以;结尾
- 在匿名内部类中可以使用外部类的属性,但是外部类却不能使用匿名内部类中定义的属性,因为是匿名内部类,因此在外部类中无法获取这个类的类名,也就无法得到属性信息