概述
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("静态内部类定义的静态方法"); } } }