java中的内部类(1、局部内部类 2、匿名内部类 3、成员内部类 4、静态内部类)
局部内部类
- 局部内部类定义在局部位置比如(方法内),就内部类有类名
- 可以直接访问外部类的所有成员,包括私有的
- 不能添加访问修饰符,因为他的位置就是一个局部变量。局部变量是不能用访问修饰符的,但是可以用final修饰,因为局部变量可以用final
- 记住:只能方法中或代码块中,它的本质还是一个类
- 局部内部类---访问----外部类:直接访问
- 外部类---访问----局部内部类:需要先创建局部内部类的对象在访问,注意注意必须要作用域内创建对象
- 外部其他类不能访问局部内部类
- 如果外部类和内部内部类的方法重名时,则遵循就近原则,如果想访问外部类的成员则使用,外部类对象.this.成员去访问
匿名内部类(重要!!!)
- 需求:假如有一个接口需要创建对象,则写一个类,实现该接口,并创建对象,但是只需要这个实现类使用一次后面不在使用
- 本质还是 一个类,内部类,该类没有名字(其实底层会给这个类分配名字),该类的本质其实还是一个对象
- 匿名内部类是定义在外部类的局部位置,比如方法中,并没有类名
- 语法:new 类或接口(参数列表){ 类体 }
- interface A{ }
- 其实匿名内部类是有类名的,只在底层可以看到, A a = new A(){ 重写接口的方法),A是一个接口,接口是不能被实例化的,但是其实他的底层,编译类型是接口,这个运行类型是一个匿名内部类
- 最底层,他会有一个类去实现了这个A接口,他的底层分配的类名是:外部类$1,这个类名是底层给我们分配的
- A a = new A(){ 重写接口的方法 },解释:new A() 其实 是创建了一个匿名内部类实现了A接口,类名是外部类+$1,创建完以后立马就new了,创建了匿名内部类的实例,并且把这个匿名内部类的实例返回给了 引用名a
- 可以直接访问外部类的所有成员,包括私有的
- 不能添加访问修饰符因为他的地位就是一个局部变量
- 应用实践
- 方式一:当做实参直接传递,简洁高效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ad { public static void main(String[] args) { //匿名内部类 a( new Tiger() { @Override public void tiger() { System.out.println( "老虎正在叫。。。。。" ); } }); } ////静态方法,形参是接口类型 public static void a(Tiger tiger){ tiger.tiger(); } } //接口 interface Tiger{ void tiger(); } |
对比:以下方式不推荐属于是 硬编码,推荐用上面的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static void main(String[] args) { a( new Animal()); } ////静态方法,形参是接口类型 public static void a(Tiger tiger){ tiger.tiger(); } } //接口 interface Tiger{ void tiger(); } class Animal implements Tiger{ @Override public void tiger() { System.out.println( "老虎正在叫。。。" ); } } |
- 在举例
12345678910111213141516171819202122232425
public
class
Phone {
public
static
void
main(String[] args) {
oppo oppo =
new
oppo();
oppo.iA(
new
A() {
@Override
public
void
fun() {
System.out.println(
"我的电话"
);
}
});
oppo.iA(
new
A() {
@Override
public
void
fun() {
System.out.println(
"我的手机"
);
}
});
}
}
interface
A{
void
fun();
}
class
oppo{
public
void
iA(A a){
a.fun();
}
}
成员内部类
- 成员内部类是定义在外部类的成员位置,并没有static
- 可以访问外部类的所有成员,包括私有的
- 可以访问修饰符,因为他的地位就是一个成员
- 作用域:和外部类其他成员一样,在外部类的成员方法中需要创建内部类的对象,在调用
- 成员内部类---访问----外部类:直接访问
- 外部类---访问----成员内部类:需要创建对象,在访问
- 如果外部类和成员内部类的方法重名时,则遵循就近原则,如果想访问外部类的成员则使用,外部类对象.this.成员去访问
静态内部类
- 静态内部类定义在外部类的成员位置,并且有static
- 可以外部类所有访问静态成员,包括私有的,但不能访问非静态的
- 可以访问修饰符,因为他的地位就是一个成员
- 作用域:和外部类其他成员一样,在外部类的成员方法中需要创建内部类的对象,在调用
- 静态内部类---访问----外部类:可以直接访问外部类的所有静态成员
- 外部类---访问----成员内部类:需要创建对象,在访问
-
public class gsg {
public static void main(String[] args) {
num.da();
}
}
class num{
private static String name = "yc";
public static void sun(){
System.out.println("hello");
}
static class dad{
public void fun(){
System.out.println("fun....."+name);//可以直接访问外部类的静态变量
sun();//直接可以访问外部类的静态方法
}
}
public static void da(){//外部类访问 静态内部类 需要创建对象
dad dad = new dad();
dad.fun();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理