Java-内部类
🔥学习的重点和难点!!后面看底层源码时,有大量的内部类
基本介绍
基本语法
内部类的分类
局部内部类 VS 匿名内部类
成员内部类 VS 静态内部类
练习
【基本介绍】
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。内部类是我们类的第五大成员(属性,构造器,方法,代码块),内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
【基本语法】
class 类名{ //外部类
class 类名{ //内部类
}
}
class 类名{ //外部其他类
}
//匿名内部类
new 类或接口(参数列表){
类体
};
【内部类的分类】
定义在外部类局部位置上(比如方法内):
(1)局部内部类 (有类名)
(2)匿名内部类 (没有类名,重点!!!!)
定义在外部类的成员位置上:
(1)成员内部类 (没用static修饰)
(2)静态内部类 (使用static修饰)
【局部内部类 VS 匿名内部类】
相同之处 :
➊定义位置:在外部类局部位置上
➋作用域 :仅在定义它的方法或代码块中。
➌可以直接访问外部类的所有成员,包括私有的;
➍如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果像访问外部类的成员,则可以使用 外部类名.this.成员 去访问,如果单单是 this 则指的是该内部类的对象
➎是一个类,也是一个局部变量
不同之处 :
| 局部内部类 | 匿名内部类🔥anonymous |
|---|---|
| 有类名 | 没有类名(其实是系统自动分配一个类名) |
| 可以用 final 修饰 | |
| / | 底层帮你创建了匿名内部类后,自动帮你 new一个实例,并且返回这个实例 |
| / | 匿名内部类只能在其作用域中用一次,但创建的对象可以使用多次 |
下面是基于接口的匿名内部类:
public class TestInterface {
public static void main(String[] args) {
Outer outer = new Outer();
outer.method();
}
}
interface IF{ //接口
void cry();
}
//需求:想使用IF接口,并创建一个对象
//背景:某个类只需使用一次,以后再不使用
class Outer{
public void method(){
//对象 obj 的编译类型:接口IF
//对象 obj 的运行类型:匿名内部类
/*
底层其实是: 系统自动分配一个类名 Outer$1
class Outer$1 implements IF{
@Override
public void cry() {
System.out.println("I'm crying...");
}
}
*/
//这个匿名内部类用一次就不能再使用了,但是对象可以反复使用
//底层帮你创建了匿名内部类后,自动帮你 new 一个实例,并且帮地址返回给你设置的 obj
IF obj = new IF() {
@Override
public void cry() {
System.out.println("I'm crying...");
}
};
obj.cry();
System.out.println(obj.getClass());
}
}
基于类的匿名内部类:


【成员内部类 VS 静态内部类】
相同之处 :
➊定义位置:在外部类成员位置上
➋作用域 :整个类体
➌可以添加任意访问修饰符,因为它的地位就是一个成员。
➍外部类想要访问这两个内部类,都需要创建对象,再访问。
➎是一个类,也是一个外部类成员
➏外部其他类访问内部类的两种方式:


不同之处 :
| 成员内部类 | 静态内部类 |
|---|---|
| 可以直接访问外部类的所有成员,包括私有的 | 可以直接访问外部类的静态成员,包括私有的;不能直接访问非静态成员 |
| 没有static修饰 | static修饰 |
| 外部其他类想要调用成员内部类需要通过外部类的实例来new这个成员内部类的实例 | 外部其他类想要调用静态内部类只需要new 外部类名.静态内部类名() |
【练习】





浙公网安备 33010602011771号