内部类
1.基本介绍
1.概括
- 一个类的内部又完整的嵌套了另一个类的结构,被嵌套的类称为内部类,嵌套其他类的类称为外部类,内部类最大的特点就是可以直接访问私有属性
2.基本语法
class Outer{
class Inner{
}
}
3.内部类的分类
1.定义在外部类局部位置上
-
局部内部类(有类名)
-
可以直接访问外部类的所有成员,包含私有的
-
不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量是不能使用修饰符的,但是可以使用final修饰,因为局部变量也可以使用final
-
作用域:仅仅在定义它的方法或代码块中
-
局部内部类----访问----->外部类的成员 [访问方式 : 直接访问]
-
外部类—访问----->局部内部类的成员 [访问方式: 创建对象,在访问(注意:必须在作用域中)]
-
外部其他类-----不能访问----->局部内部类
-
如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)去访问
public class LocalInnerClass { public static void main(String[] args) { Outer outer = new Outer(); outer.msg();//10 } } class Outer{ private int age = 10; //局部内部类是定义在外部类的局部位置,通常在方法中 public void msg(){ class Inner{ private int age = 20; //可以直接访问外部类的所有成员,包括私有成员 public void getAge(){ System.out.println(Outer.this.age);//10 } } Inner inner = new Inner(); inner.getAge(); } }
-
-
匿名内部类(没有类名 [重点])
-
说明:匿名内部类是定义在外部类的局部位置
-
本质是类,且内部类,同时还是一个对象
-
匿名内部类的基本语法
-
new 类或接口(参数列表){ 类体 };
/** * 演示匿名内部类的使用 */ public class AnonymousInner_ { public static void main(String[] args) { Outer_4 outer_4 = new Outer_4(); outer_4.method();//工作ing..... \n 重写匿名内部类的test方法 } } //外部类 class Outer_4{ private int num_1 = 10; public void method(){ //基于接口的匿名内部类 //只在此处使用一次 //worker的编译类型 As_1 worker的运行类型 匿名内部类(底层会分配一个类名,外部类的名称$1) /* class Outer_4$1 implements As_1{ @Override public void cry() { System.out.println("工作ing....."); } } */ //JDK底层在创建匿名内部类Outer_4$1,立即就创建了Outer_4$1实例,并且把地址返回给worker //匿名内部类只能使用一次 As_1 worker = new As_1() { @Override public void cry() { System.out.println("工作ing....."); } }; worker.cry(); /** * 基于类的匿名内部类 * 1.father 编译类型 Father * 2.father 运行类型 Outer_4$2 * 3.底层会创建匿名内部类 * class Outer_4$2 extends Father{ * @Override * public void test(){ * System.out.println("重写匿名内部类的test方法"); * } * } * 4.同时也直接返回了 内名内部类 */ Father father = new Father("jack"){ @Override public void test(){ System.out.println("重写匿名内部类的test方法"); } }; father.test(); } } //接口 interface As_1{ public void cry(); } class Father{ public Father(String name){ super(); } public void test(){ } }
-
-
匿名内部类的注意事项和细节
-
匿名内部类既是一个类的定义,同时它本身也是一个对象,语法上看,既有定义类的特征,也有创建对象的特征【代码演示】
//方式一【推荐使用】 new A(){ @Override public void test(){ System.out.println("Hello"); } }.test(); //方式二 A a = new A(){ @Override public void test(){ System.out.println("hello"); } }; a.test();
-
可以直接访问外部类的所有成员,包含私有的
-
不能添加访问修饰符,因为它的地位就是一个局部变量
-
作用域: 仅仅在定义它的方法或代码块中
-
匿名内部类—访问—>外部类成员 [访问方式: 直接访问]
-
外部其他类 — 不能访问------>匿名内部类
-
如果外部类和匿名内部类的成员变量重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
-
-
2.定义在外部类的成员位置上
-
成员内部类(没用 static修饰)
-
说明:成员内部类是定义在外部类的成员位置,并且没有static修饰
-
可以直接访问外部类的所有成员,包含私有的
-
可以添加任意修饰符,因为它的地位就是一个成员
class Outer{ private int num = 10; public String name = "张三"; //注意:成员内部类是定义在外部类的成员位置上 class Inner{ public void say(){ System.out.println("成员内部类 num="+num); } } }
-
作用域:和外部类的其他成员一样,在外部类的成员方法中创建成员内部类对象,在调用方法
-
成员内部类—访问---->外部类[ 直接访问 ]
-
外部类—访问---->内部类 [创建对象,在访问 ]
-
外部其他类—访问---->成员内部类
//方式一 Outer outer = new Outer(); Outer.Innter innter = outer.new Innter(); //方式二 Innter innter = new Outer().new Innter(); //方式三 Innter innter = new Outer().getInnterInstance();
-
如果成员内部类的成员和外部类的成员重名了,遵守就近原则
-
如果外部类想访问,可以通过 外部类名.this.变量名 来访问
-
-
静态内部类(使用static修饰)
-
说明:静态内部类是定义在外部类的成员位置,并且有static修饰
-
可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
-
可以添加任何修饰符修饰,因为它的地位就是一个成员
-
作用域:同其他的成员一样,为整个类体
class Outer{ private int num = 30; public String name = "张三"; static String username = "root"; static class Innter{ private int num = 30; public void test_1(){ System.out.println("测试类运行"); System.out.println("username = "+username); } } }
-
静态内部类 —访问---->外部类 [直接访问所有静态成员]
-
外部类—访问---->静态内部类 [ 创建内部类对象,在访问 ]
-
外部其他类—访问—>静态内部类
//因为静态内部类,是可以通过类直接访问(但是要满足访问权限) //方式一 Outer.Innter innter = new Outer.Innter(); //方式二 --- 1 静态和非静态都可以使用 Outer.Innter innter = (new Outer()).getInnter(); //方式二 --- 2 静态 Outer.Innter innter = Outer.getInnter();
-
如果外部类和静态内部类的成员变量重名,静态内部类访问的时候,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员 )去访问
-