内部类的分类
内部类的定义:定义在一个类的内部的类就是内部类。
就像是定义类一样,类内部的变量有局部变量和成员变量,在类中方法外的变量为成员变量,在方法重点的变量是局部变量。
所以内部类也分为:成员内部类 和 局部内部类。
内部类的特别之处:可以用static 修饰类。内部类可以随意访问外部类的成员变量和成员方法,哪怕是私有的(类比一下成员方法调用成员变量,静态的只能访问静态的),需要注意的是如果内部类只要有静态成员,那么该内部类也要申明为静态。
eg:
## 成员内部类:
class Outer {
private final int num =10;
private void outPrint(){
System.out.println("外部类的方法");
}
class Inner{
public void innerPrint(){
outPrint();
System.out.println("成员内部类,外部类的成员变量"+num);
}
}
}
public class OuterDemo{
public static void main(String[] args) throws CloneNotSupportedException {
// 创建内部类的对象来访问内部类的方法
Outer.Inner outAndInner = new Outer().new Inner();
//内部类访问了,外部类的私有方法
outAndInner.innerPrint();
}
}
//假如,内部类是静态的,而且内部类的方法也是静态的,那么内部类的方法调用就犹如 一般类中静态成员的调用一样简单了
eg:
class Outer {
private static int num =10;
static class Inner{
//内部类方法为静态
public static void innerPrint(){
System.out.println("成员内部类"+num);
}
//内部类方法为非静态
public void innerPrint02(){
System.out.println("成员内部类"+num);
}
}
}
public class OuterDemo{
public static void main(String[] args) throws CloneNotSupportedException {
//内部类和内部类的方法均为静态。
Outer.Inner.innerPrint();
//假如只有内部类是静态,而静态类中的方法不为静态呢?
Outer.Inner outAndInner = new Outer.Inner();
//当内部类为静态时候,内部类对象的创建方法
outAndInner.innerPrint02();
}
}
## 成员内部类的测试
class Outer {
private int num = 10;
class Inner {
int num = 20;
//内部类方法为静态
public void innerPrint() {
int num = 30;
System.out.println("成员内部类" + num);//局部变量的num
System.out.println("成员内部类" + this.num);//本类中的变量num
System.out.println("成员内部类" + Outer.this.num);//外部类的变量num
}
//内部类方法为非静态
public void innerPrint02() {
System.out.println("成员内部类" + num);
}
}
}
public class OuterDemo{
public static void main(String[] args) throws CloneNotSupportedException {
Outer.Inner outAndInner = new Outer().new Inner();
outAndInner.innerPrint();
}
}
## 局部内部类
内部类在外部类的局部位置的内部类位局部内部类
class Outer {
private int num2 = 30;
public void outerMathod(){
int num = 20;//在编译过程中会自动变成 final修饰的变量 final int num = 20;
//内部类访问外部类的局部变量时,要将变量申明位 final修饰的自定义常量,因为在虚拟机的调用过程中,方法从方法区被调用之后
//就会被垃圾回收回收,而*局部变量随着方法的调用完成而消失*,内部类的对象再去调用内部类的*方法去访问 外部类的局部变量*,
//这时候如果局部变量没有申明为常量的话,就会出现找不到该变量的异常
class Inner {
public void innerPrint(){
//内部类访问局部变量
System.out.println("成员内部类"+num);
}
}
Inner inner = new Inner();
inner.innerPrint();
}
}
public class OuterDemo{
public static void main(String[] args) throws CloneNotSupportedException {
Outer outer = new Outer();
outer.outerMathod();
}
}
匿名内部类
内部的的引申就是我们经常会用到的匿名内部类了,他的定义是什么呢?
前提:存在一个类或者接口,这个类可以是抽象的也可以是具体类。
格式: new 类或者接口名(){
重写方法
}
匿名内部类的实质:继承了某类 或者 实现了某个接口,并且重写了方法的子类匿名对象。
interface Inner{
void metnod();
}
class Outer {
public void test(){
new Inner(){
@Override
public void metnod() {
System.out.println("匿名内部类");
}
};
}
}
public class OuterDemo{
public static void main(String[] args) throws CloneNotSupportedException {
Outer outer = new Outer();
outer.test();
}
}
创建线程的时候:
new Thread(){
@Override
public void run() {
System.out.println("重写run方法,做你想做的事");
}
}.run();
}
这也是我们经常用到的匿名内部类的场景,继承 Thread 类,得到了匿名内部类 ,他的本质也是线程的子类,再 .run方法,去运行线程。