概述
1.基本定义
- 可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
- 内部类一般包括四种:成员内部类、局部内部类、匿名内部类和静态内部类
2.内部类特点
- 内部类是一种编译时的语法,编译后生成的两个类是独立的两个类。
- 内部类可以访问外部类的任何成员,但外部类不能直接访问内部类的成员。
- 内部类可为静态,可以用public、protected、private修饰,而外部类只能使用public和缺省的包访问权限。
- 用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
四种内部类
1.成员内部类
- 成员内部类是最普通的内部类,它的定义为位于另一个类的内部
- 作为类的一个方法存在,地位与成员方法相同
//外部类:不可用private修饰,public和缺省都可以
//公有的外部类只能定义一个,而且名字必须与文件名一致
public class OuterClassA {
//成员属性和成员方法
private String outterstr;
private int num = 10;
public void setOutterstr(String outterstr) {
this.outterstr = outterstr;
}
public String getOutterstr() {
return outterstr;
}
//不能直接访问内部类的成员
//先创建内部类的对象,再访问内部类的成员
public void outerFun(){
//setInnerStr("abc");
InnerClassA innerClassA = new InnerClassA();
innerClassA.setInnerStr("abc");
//System.out.println(InnerClassA.this.num);
}
//成员内部类(地位与成员方法一致)
//不会再出外部类的地方使用
public class InnerClassA {
//成员属性和方法
private String innerStr;
private int num = 20;
public void setInnerStr(String innerStr) {
this.innerStr = innerStr;
}
public String getInnerStr() {
return innerStr;
}
public void innerFun(){
//成员内部类中,可以访问外部类的所有成员
setOutterstr("abc");
System.out.println(num);//内部类定义的num属性
System.out.println(this.num);//内部类定义的num属性
System.out.println(OuterClassA.this.num);//外部类定义的num属性
}
}
}
- 创建成员内部类的对象,先创建外部类的对象,通过外部类加点号的方法创建内部类对象
OuterClassA outerClassA = new OuterClassA();
InnerClassA innerClassA = outerClassA.new InnerClassA();
OuterClass.InnerClass inner = new OuterClass().new InnerClass ();
2.局部内部类
- 局部内部类是定义在一个方法或者一个作用域里面的类
- 地位同局部变量
- 局部内部类不能加修饰符public、protected和private,其范围为定义它的代码块。
- 可以访问外包方法之外的外部类之内的所有成员。还可以访问所在外包方法中的参数。
- 局部内部类只能访问局部中被final修饰的局部变量。
- 局部内部类不能声明为接口。
public class OuterClassb {
//成员属性和成员方法
private String outterstr;
private int num = 10;
public void setOutterstr(String outterstr) {
this.outterstr = outterstr;
}
public String getOutterstr() {
return outterstr;
}
public void outerFun(){
//局部常量,在局部内部类中不允许改变值(final可以省略)
int num = 0;
//局部内部类,限定在方法内部(地位同局部变量)
class InnerClassB{
//成员属性和方法
String innerStr;
public void setInnerStr(String innerStr) {
this.innerStr = innerStr;
}
public String getInnerStr() {
return innerStr;
}
public void innerFun(){
//局部内部类中可以直接访问外部类的所有成员属性和方法
outterstr = "abc";
setOutterstr("abc");
}
}
//创建局部内部类的对象
InnerClassB innerClassB = new OuterClassA().new InnerClassB();
}
}
- 要想使用局部内部类时,需要生成外部类对象,通过外部类对象调用外包方法,在方法中才能调用局部内部类。
3.匿名内部类
- 匿名类是不能有名字的类,它们不能被引用,只能在创建时用 new 语句来声明它们。
- 匿名类没有类名,它必须继承一个类或是实现一个接口。不能有显示的extends和implements子句。
- 匿名类不能有构造函数并且只能一次性的创建其对象
- 匿名类可以在方法体中,也可以在参数列表中。
public static void staticFun(Itext iTest){
iTest.test();
}
staticFun(new Itext() {
//内部类定义范围
@Override
public void test() {
System.out.println("参数中使用匿名内部类");
}
});
- 匿名内部类必须实现它的抽象父类或者接口里的所有抽象方法。
public interface Itext {
void test();
}
public class OuterClassC {
private String outterstr;
private int num = 10;
public void setOutterstr(String outterstr) {
this.outterstr = outterstr;
}
public String getOutterstr() {
return outterstr;
}
public void outerFun(){
//匿名内部类(地位同局部变量,是一种特殊的局部内部类)
//定义的是一个接口的实现类,或者是基类的派生类
//匿名内部类的定义和对象的创建在同一个语句中
//匿名内部类只有唯一的一个对象
Itext iTest = new Itext() {
//大括号里边就是匿名内部类的范围
@Override
public void test() {
System.out.println("在匿名内部类中重写的方法");
}
};//不要丢分号(;)
iTest.test();//执行的重写的方法
}
}
4.静态内部类
- 静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字
static
- 静态内部类的对象可以直接生成。
- 静态内部类能直接访问外部类的静态成员,不能直接访问外部类的非静态属性成员(外部类的对象访问)。
- 静态内部类里面可以定义静态成员,其他内部类不可以。
- 如果内部类中定义了静态成员,该内部类也必须定义为静态的。
public class OuterClassD {
//成员属性和成员方法
private String outerStr;
public void setOuterStr(String outerStr) {
this.outerStr = outerStr;
}
public String getOuterStr() {
return outerStr;
}
public static void fun() {
System.out.println("外部类的静态方法");
}
//静态内部类
public static class InnerClassD{
//成员属性和方法
private String innerStr;
private int num = 20;
public void setInnerStr(String innerStr) {
this.innerStr = innerStr;
}
public String getInnerStr() {
return innerStr;
}
//可以定义静态的成员(其他内部类中不允许)
public static void innerFun() {
//静态内部类中不能访问外部类的非静态成员
fun();
System.out.println("静态内部类定义的静态方法");
}
}
}