文章目录
前言
内部类分为4种,常用的为匿名内部类
一、内部类是什么?
一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。是我们类的第五大成员【类的五大成员:属性,方法,构造器,代码块,内部类】,内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
二、定义在外部类局部位置
1.局部内部类(有类名)
1.可以直接访问外部类的所有成员,包含私有的。2.不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰,因为局部变量也可以使用final。
3.作用域:仅仅在定义它的方法或代码块中。
4.局部内部类---访问---->外部类的成员[访问方式:直接访问]
5.外部类---访问---->局部内部类的成员[访问方式:创建对象,再访问(注意:必须在作用域(方法或者代码块)内)]
6.外部其他类---不能访问----->局部内部类(因为局部内部类地位是一个局部变量)
7.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
【演示】 System.out.println(“外部类的n2=”+外部类名.this.n2);
代码示例:
public class Outer01 {
public static void main(String[] args) {
//
Outer02 outer02=new Outer02();
outer02.m1();
}
}
class Outer02{//外部类
private int n1=100;
private int n2=100;
private void m2() {
System.out.println("Outer02 m2()");
}//私有方法
public void m1() {//方法
//局部内部类是定义在外部类的局部位置,通常在方法
class Inner02{//局部内部类(本质任然是一个类)
private int n2=80;
public void f1() {
//可以直接访问外部类的所有成员,包含私有的
System.out.println("n1="+n1);
m2();
/*如果外部类和局部内部类的成员重名时,默认遵循就近原则
**如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
**例如下面n2是80,Outer02.this.n2是100
**Outer02.this本质是外部内的对象,即调用了此m1的对象
*/
System.out.println("n2="+n2+",外部类n2="+Outer02.this.n2);
}
}
/*外部类---访问---->局部内部类的成员
* [访问方式:创建对象,再访问(注意:必须在作用域(方法或者代码块)内)]
*/
Inner02 inner02 = new Inner02();
inner02.f1();
}
}
2.匿名内部类(无类名)
1.本质是类。2.内部类,特性同上。
3.没有类名,但没有完全没有名字,系统底层会给名字,不能有自己的构造器
4.同时是一个对象
5.主要场景:使用一次对象,后续不再使用的地方
代码示例:
public class AnonymousInner {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Outer03 outer03=new Outer03();
outer03.method();
}
}
class Outer03{//外部类
private int n1=10;
public void method() {
//基于接口的匿名内部类
//使用目的,简化开发,不再写一个类实现接口
/*
* *底层会分配类名 Outer03$1
* class Outer03$1 implements A{
*
public void cry() {
System.out.println("汪汪");
}
* }
*/
//编译类型:A
//运行类型:就是匿名内部类,Outer03$1
//jdk底层创建匿名内部类Outer03$1,立马创建实例,把地址返回给dogA
//生成实例后,底层匿名内部类就无了
A dogA = new A() {
public void cry() {
System.out.println("汪汪");
}
};
dogA.cry();
System.out.println("dogA的运行类型="+dogA.getClass());
//基于类的匿名内部类
//编译类型 Father
//运行类型 Outer03$2
/*
* class Outer03$2 extends Father{
public void text() {
System.out.println("重写text方法");
}
};
*/
Father father = new Father("txt") {
public void text() {
System.out.println("重写text方法");
}
};
System.out.println("father的运行类型"+father.getClass());
father.text();
}
}
interface A{//接口
public void cry() ;
}
class Father{//类
public Father(String name) {//构造器
}
public void text() {
}
}
三、定义在外部类成员位置
1.成员内部类(无static修饰)
1.成员内部类是定义在外部类的成员位置,无static修饰
2.可以直接访问外部类的所有成员,包含私有的。
3.可以添加访问修饰符(public、protected、private),因为它的地位就是一个成员。
4.作用域与外部类的其他成员一样
5.成员内部类—访问---->外部类成员【访问方式:直接访问】
6.外部类—访问------>内部类【访问方式:创建对象,再访问】
7.外部其他类—访问---->成员内部类(如代码举例)
8.如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
代码示例:
public class MemberInner {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Outer04 outer04 = new Outer04();
outer04.method1();
//外部其他类访问成员内部类的两种方式
//①
Outer04.Inner01 inner01 = outer04.new Inner01();
inner01.say();
//②利用成员内部类所在外部类的方法,放回一个对象
Outer04.Inner01 inner02 = outer04.getInner01();
inner02.say();
}
}
class Outer04{
private int n1=10;
public String name="阿巴阿巴";
class Inner01{//成员内部类
//可以直接访问外部类的所有成员
public void say() {
System.out.println("n1="+n1+",name="+name);
}
}
//在方法中调用成员内部类
public void method1() {
Inner01 inner01 = new Inner01();
inner01.say();
}
//返回成员内部类的方法
public Inner01 getInner01() {
return new Inner01();
}
}
2.静态内部类(使用static修饰)
1.静态内部类是定义在外部类的成员位置,并且有static修饰
2.可以直接访问外部类的所有静态成员,但不能访问非静态成员。
3.可以添加访问修饰符(public、protected、private),因为它的地位就是一个成员。
4.作用域与外部类的其他成员一样
5.静态内部类—访问---->外部类静态成员【访问方式:直接访问】
6.外部类—访问------>静态内部类【访问方式:创建对象,再访问】
7.外部其他类—访问---->成员内部类(如代码举例)
8.如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问
代码示例:
public class StaticInner {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Outer05 outer05 = new Outer05();
outer05.method1();
//外部其他类访问静态内部类二种方式
//①
Outer05.Inner02 inner02 = new Outer05.Inner02();
inner02.say();
//②利用静态内部类所在外部类的方法,放回一个对象
Outer05.Inner02 inner03 = outer05.getInner02();
inner03.say();
}
}
class Outer05{
private int n1=10;
private static String name ="萨达";
public static class Inner02{
public void say() {
System.out.println(name);
}
}
public void method1() {
Inner02 inner02 = new Inner02();
inner02.say();
}
//返回静态内部类的方法
public Inner02 getInner02() {
return new Inner02();
}
}