Java内部类一般分为四种分别为:成员内部类、静态内部类、局部内部类、匿名内部类
从所在位置上划分:
①类成员作用域:
1.成员内部类
2.静态内部类
②类方法内局部作用域:
1.局部内部类
2.匿名内部类
一、内部类的定义和种类
1.成员内部类
最普通的内部类:即在一个类的内部定义一个类
public class Outer {
public class Inner{
}
}
Inner即为Outer的成员内部类
2.静态内部类
与成员内部类形式上的区别:拥有static声明;其内部可以存在static元素,而其他内部类不能存在static元素(需要static final修饰),不能嵌套static类;静态内部类却可以嵌套成员内部类
public class Outer {
public static class Inner{
}
}
3.局部内部类
在(无论是静态还是非静态方法,甚至是构造方法里)方法体作用域内
public class Outer {
public void get() {
class Inner{
}
}
}
4.匿名内部类
在(无论是静态还是非静态方法,甚至是构造方法里)方法体内拥有一个没有名字的内部类
接口:
public interface Content {
String getName();
}
匿名内部类:
public class Outer {
public Content get() {
return new Content() {
@Override
public String getName() {
return "匿名内部类";
}
};
}
}
实际上该匿名类是Content接口的子类,然后自动向上转型为Content,不能对构造器进行重载
二、内部类的访问权限
1.成员内部类
public class Outer {
//公共内部类
public class InnerPublic{
}
//默认内部类
class InnerDefault{
}
//私有内部类
private class InnerPrivate{
}
//继承内部类
protected class InnerProtected{
}
}
就如同普通的类一样,成员内部类的访问控制符依旧为公共、默认、私有、继承四个
2.静态内部类(嵌套类)
同成员内部类:
public class Outer {
//公共静态内部类
public static class InnerPublic{
}
//默认静态内部类
static class InnerDe{
}
//私有静态内部类
private static class InnerPrivate{
}
//继承静态内部类
protected static class InnerProtected{
}
}
3.局部内部类
无法被作用域外访问,所以不能加访问限定符
4.匿名内部类
同局部内部类
三、内部类的创建
1.成员内部类
①外围类外创建
public class Test {
public static void main(String[] args) {
Outer outer=new Outer();
Outer.InnerPublic innerPublic=outer.new InnerPublic();
}
}
在Outer类外创建内部类时(Test和Outer不在一个包内,受到内部类访问条件制约,只能访问InnerPublic),需要外部类的引用.new,并且类名要限定(外部类.内部类)。
②外围类里创建
public class Outer {
//公共内部类
public class InnerPublic{
}
//默认内部类
class InnerDefault{
}
//私有内部类
private class InnerPrivate{
}
//继承内部类
protected class InnerProtected{
}
public InnerPrivate getInnerPrivate() {
return new InnerPrivate();
}
public static void main(String[] args) {
Outer outer=new Outer();
InnerPrivate innerPrivate=outer.new InnerPrivate();
}
}
在Outer类里创建内部类时,由于static方法里是不存在this(不存在外部类的引用),所以在static方法里依旧需要new 外部类,
然而getInnerPrivate方法可以直接new 内部类
2.静态内部类
public class Outer {
public static class Inner{
}
public static void main(String[] args) {
new Inner();
}
}
静态内部类是不需要外部类的引用,所以可以直接new
3.局部内部类
public class Outer {
public void get() {
class Inner{
}
Inner inner=new Inner();
}
}
就像正常类一样创建即可,但是要注意作用域(作用域外无法访问该类)
4.匿名内部类
public Content get() {
return new Content() {
@Override
public String getName() {
return "匿名内部类";
}
};
}
类的实例化
四、内部类拥有外围类的所有元素的访问权(包括多层嵌套)
1.成员内部类、局部内部类、匿名内部类
public class Outer {
private String name="Outer";
class Inner{
public void getName() {
System.out.println(name+".Inner");
}
}
public static void main(String[] args) {
Outer outer=new Outer();
Inner inner=outer.new Inner();
inner.getName();
}
}
输出结果:
由于内部类在创建的时候便秘密的捕获了外围类的引用(由编译器处理),所以内部类可以随意访问外围类的方法和字段
2.静态内部类
不能访问外围类的非静态元素(静态的可以访问)
五、获取外围类的引用
外围类名.this (不能在静态方法、静态类中使用)
六、内部类和接口的搭配使用
接口:
public interface Content {
String getName();
}
外部类和内部类:
public class Outer {
private class IContent implements Content{
@Override
public String getName() {
return "IContent";
}
}
public Content getIContent() {
return new IContent();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Outer outer=new Outer();
Content content=outer.getIContent();
System.out.println(content.getName());
}
}
输出结果:
由于私有内部类的访问控制,加上返回私有类的向上转型,导致了只能使用接口定义的方法,甚至向下转型使用自己在私有类中扩展的方法都是不能的(私有内部类类名不能访问)