内部类的作用:
- 提供很好的封装,不允许同一个包中的其他类访问!
- 内部类成员能直接访问外部类的私有数据
- 匿名内部类适用于创建仅仅需要使用一次的类
内部类分类:
- 非静态内部类
- 静态内部类(类内部类)
- 成员内部类
- 匿名内部类
非静态内部类注意事项:
- 非静态内部类的成员可访问外部类的private成员,反过来不成立
—原因:外部类对象访问非静态内部类成员时,可能非静态内部类对象根本不存在!而非静态内部类对象访问外部类成员时,外部类对象一定存在! - 不允许在外部类的静态成员中直接使用非静态内部类!
- 非静态内部类里不能有静态方法,静态成员变量,静态初始化代码块!
总之:就是一个先来后到问题,先有外部类,才能有非静态内部类
静态内部类注意事项:
- static修饰的,所以这个内部类属于外部类本身,也叫类内部类!
- 静态内部类可以包含静态成员,也能包含非静态成员,静态成员不能访问非静态成员!(又是先来后到问题)
- java允许在接口中定义内部类,默认使用public static修饰!
局部内部类
把一个内部类放在方法里定义,这个内部类就是局部内部类,仅在该方法里有效!不能有访问控制符和static修饰符!作用域是当前方法!很少使用!
注意事项:
- 只能用默认访问修饰符
匿名内部类
创建那种只需要一次使用的类,必须继承一个父类或者实现一个接口!
语法:
new 实现接口()|父类构造器(实参列表)
{
//匿名内部类的实体部分
}
匿名内部类不能是抽象类,不能定义构造器!
java8以前,java要求被局部内部类,匿名内部类访问的局部变量必须使用final修饰,java8以后,这个限制取消了!
使用静态内部类和非静态内部类
声明变量的语法完全一样
格式:OuterClass.InnerClass varName
创建的时候有所区别:
非静态内部类:必须使用外部类对象调用构造器
Out.In in=new out().new In();
静态内部类:只需使用外部类就能调用构造器
StaticOut.StaticIn in=new StaticOut.StaticIn();
实例:
抽象类I,含有抽象方法getPrice()
public abstract class I {
public abstract double getPrice();
}
TestClass包含四种内部类!
public class TestClass {
//成员变量
private int i=0;
//成员方法
//I是一个抽象类,含有抽象方法
public void test1(I i){
System.out.println("成员方法");
}
//成员内部类Inner2,修饰符public
public class Inner2{
}
//成员内部类Inner3,修饰符protected
protected class Inner3{
}
//成员内部类Inner1,修饰符默认
class Inner1{
}
//成员内部类(就是作为外部类的成员)Inner,修饰符private
private class Inner{
}
//成员方法
public void test(){
//局部内部类(内部类定义在方法和作用域内)
/*编译器报错,修饰符不能是public*/
public class Inner4{
}
//局部内部类
/*编译器报错,修饰符不能是protected */
protected class Inner6{
}
//局部内部类
class Inner5{
}
//局部内部类
/*编译器报错,修饰符不能是private*/
private class Inner7{
}
}
//静态内部类(static+成员内部类)
public static class Inner10{
}
protected static class Inner11{
}
static class Inner9{
}
private static class Inner8{
}
//匿名内部类
public static void main(String[] args) {
TestClass test2=new TestClass();
test2.test1(new I(){
@Override
public double getPrice() {
System.out.println("匿名内部类");
return 0;
}
});
}
}