内部类
1.内部类
1.1 成员内部类
1.2 局部内部类
1.3 静态内部类
1.4 匿名内部类
第一节 内部类
内部类:一个类中嵌套(包含)另外一个类。包含的类叫内部类,外层类叫外部类。
成员内部类:
局部内部类:
静态内部类:
匿名内部类:
1.1 成员内部类
作为外部类的成员存在,与成员变量和成员方法平级关系。
1.1.1 声明:
public class Out{
//成员变量
//成员方法
//成员内部类
访问权限 class In{
//成员变量
//成员方法
}
}
1.1.2 语法说明:
成员内部类的访问权限:任意的
1.1.3 如何创建成员内部类的对象:
由于成员内部类作为外部类的成员存在,若想访问类成员需要通过对象,所以成员内部类对象需要通过外部类 对象创建
语法:
//创建外部类对象
Out o = new Out();
//通过外部类找到内部类,通过外部类对象创建内部类对象
Out.In i = o.new In();
一步完成:
Out.In i2=new Out().new In();
1.1.4 如何在成员内部类中访问外部类的成员:
1.当外部类的属性和内部类属性不同名时,可以直接访问
2.当外部类属性与内部类属性同名时,格式:
外部类名.this.属性名
通过以上格式在内部类中访问外部类的同名属性
3.成员内部类中不能包含静态成员
1.1.5 成员内部类的字节码文件格式:
外部类名$内部类名.class
代码实现:
public class Out {
//成员变量
int a = 2;
//成员方法
public void fun() {
System.out.println(a);
}
//成员内部类
public class In{
//成员内部类的成员变量
int a = 3;
//成员内部类的成员方法
public void fun() {
Out.this.fun();
System.out.println(a);
System.out.println(Out.this.a);
}
}
}
import memberInnerClass.Out.In;
public class Test {
public static void main(String[] args) {
//先创建外部类对象
Out o = new Out();
//System.out.println(o.a);
//o.fun();
//创建成员内部类的对象
//通过外类的对象创建成员内部类对象
In i = o.new In();
//System.out.println(i.b);
i.fun();
}
}
1.2 局部内部类
作为局部成员存在,和局部变量平级。
1.2.1 声明:
public class Outer{
//成员变量
//成员方法
//局部内部类所在的方法
public void fun(){
//功能代码
//局部内部类
访问权限 class Inner{
//局部内部类的成员变量
//局部内部类的成员方法
}
}
}
1.2.2 说明:
局部内部类的访问权限:只能是默认
1.2.3 如何创建局部内部类对象:
直接在局部内部类所在的方法中创建对象并调用方法
1.2.4 如何在局部内部类中访问外部类的属性:
1.不同名,直接访问
2.同名,外部类名.this.属性名
3 局部内部类中不能包含静态成员。
4 局部内部类中访问局部变量,局部变量必须是final 常量 ,从jdk1.8之后final可以省略
1.2.5 字节码文件:
外部类名$编号内部类名.class
代码实现:
public class Outer {
//成员变量
int a = 3;
//成员方法
public void fun() {
class Inner{}
System.out.println("外部类的fun");
}
//局部内部类所在的方法
public void fun3() {
class In{}
//局部内部类
class Inner{
//成员变量
int a = 10;
//成员方法
public void fun() {
Outer.this.fun();
System.out.println(a);
System.out.println(Outer.this.a);
System.out.println("局部内部类的fun方法");
}
}
Inner i = new Inner();
i.fun();
}
}
public class Test {
public static void main(String[] args) {
Outer o = new Outer();
//局部内部类具有作用域,所以调用外部类对象的fun3方法时会声明局部内部类并创建对象调用方法
o.fun3();
}
}
1.3 静态内部类(重点)
static关键字用法:修饰成员变量,成员方法,代码块
static关键字的第四个用法,修饰内部类(有要求的)
static修饰的内部类是静态内部类
static只能修饰类成员
使用static修饰的成员内部类是静态内部类
1.3.1 声明:
public class Out{
访问权限 static class In{
}
}
1.3.2 说明:
访问权限:任意的,一般使用public
使用static修饰的内部类,自动提升为普通类,相当于一个独立的类,和外部类级别相同
1.3.3 创建对象:
不需要外部类的对象,可以直接创建静态内部类的对象
格式:外部类.内部类 标识符 = new 外部类.内部类构造方法
1.3.4 访问外部类的成员:
1 静态内部类能直接访问外部类的静态成员
2 非静态的成员只能通过创建外部类对象访问
3 静态内部类中可以包含静态成员
1.3.5 字节码文件格式:
外部类名$内部类名.class(与成员内部类一样)
代码实现:
public class OuterClass {
static String s = "hello";
int a = 10;
public void fun() {
System.out.println("外部类的fun");
}
//静态内部类
public static class InnerClass{
int b = 20;
public void fun() {
System.out.println(s);
System.out.println();
System.out.println("内部类的fun");
}
}
}
import staticInnerClass.OuterClass.InnerClass;
public class Test {
public static void main(String[] args) {
//可以不创建外部类对象,直接创建静态内部类对象
InnerClass i = new InnerClass();
i.fun();
}
}
1.4 匿名内部类
1.4.1 什么是匿名内部类:
没有名字的内部类
1.4.2 原理产生原因:
由于接口和抽象类不能创建对象,若一个接口的实现类只需要使用一次,或一个抽象类的子类只需要使用一次,可以使用匿名内部类,匿名内部类只能创建一个对象
代码实现:
public interface I {
public abstract void fun();
}
public class Test{
public static void main(Strng[]args){
I i = new I(){
public void fun(){
//功能代码
}
};
i.fun1();//使用匿名内部类的对象(接口引用)调用匿名内部类中重写的接口中的方法
}
}
1.4.3 匿名内部类的注意事项:
1 匿名内部类中必须把抽象方法全部实现
2 匿名内部类中可以声明独有的属性和方法,但是由于接口引用不能访问实现类中独有的属性和方法,所以一般不在匿名内部类中声明独有的属性和方法
3 匿名对象:若在匿名内部类中声明了独有的方法或属性,可以使用匿名对象访问,不能通过对象名.方法名()访问。
1.4.4 lambda 表达式
入门使用
USB leishe= ()->System.out.println("镭蛇和电脑连接成功,开始工作");
代码实现:
public static void main(String[]args){
//匿名对象调用成员方法
new I(){
public void fun(){}
public void fun1(){
System.out.println("匿名内部类的fun1");
}
}.fun1();//使用匿名内部类的匿名对象调用匿名内部类中独有的方法
//new Animal().eat();
}
1.4.4 匿名内部类的字节码文件格式:
测试类$编号.class
匿名内部类只能使用一次,即便两次声明的匿名内部类完全一致,也是两个匿名内部类
总结
1 内部类
1.1 成员内部类
成员内部类和非静态属性、方法 级别相同
注意:
成员内部类可以直接访问外部类的非静态的属性和方法
成员内部类可以访问外部类的静态属性和方法
成员内部类中属性及方法和外部类的属性及方法相同时使用 外部类名.this.属性|方法
成员内部类中不能包含静态属性和方法
1.2 局部内部类
局部内部类,是包含在方法中,使用范围只限制在方法内。
注意:
局部内部类可以直接访问外部类的非静态的属性和方法
局部内部类可以访问外部类的静态属性和方法
如果局部内部类中属性及方法和外部类的属性及方法相同 外部类名.this.属性|方法
局部内部类不能包含静态属性和方法
局部内部类使用局部变量,局部变量必须是常量 final修饰
1.3 静态内部类
静态内部类:相当于一个外部类
只有内部类才可以是静态的
注意:
静态内部类可以直接访问外部类的静态属性和方法
静态内部类不能直接访问外部类的非静态属性和方法,需要创建对象访问
静态内部类中可以包含静态成员
1.4 匿名内部类
匿名内部类就是内部类的简写,主要用在接口中创建对象
Usb mouse=new Usb(){
public void service(){
}
};
mouse.service();
面试题
//要求:使用已知的变量,在控制台输出30,20,10。
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}