Java内部类总结
Keane1998 人气:3成员内部类
- 内部类可以访问外部类的所有成员。
- 通过
外部类.this.*
访问外部类同名成员。 - 通过
外部类.内部类 name=new 外部类().内部类()
实例化对象。 - 内部类中不能有任何static成员。
public class InnerClass1 {
public int a;
protected double b;
char c;
private String d;
InnerClass1(int a){
this.a=a;
}
class inner{
int a;
inner(int a){
this.a=a;
}
private void A(){
System.out.println(a);
System.out.println(this.a);
System.out.println(InnerClass1.this.a);
}
public void B(){
System.out.println(b);
}
}
public static void main(String[] args) {
InnerClass1.inner inner=new InnerClass1(10).new inner(5);
inner.A();
inner.B();
}
}
局部内部类
- 定义在方法里,不能有修饰符,只能在方法里使用。
- 只能使用外部类的final成员。
- 除了装逼暂时想不出这东西有什么用了...
/**
* 局部内部类
*/
public class InnerClass2 {
final static int a=5;
public static void main(String[] args) {
class inner{
int sum(int n){
int ans=0;
for(int i=1;i<=n;i++){
ans+=i;
}
return ans+a;
}
}
System.out.println(new inner().sum(5));
System.out.println(new inner().sum(15));
}
}
静态内部类
- 静态内部类较为独立,不依赖于外部类,通过
外部类.内部类 name=new 外部类.内部类()
实例化对象,不需要创建外部类实例。 - 只能访问外部类的static成员。
/**
* 静态内部类
*/
public class InnerClass3 {
int a=5;
static int b=10;
static class inner3{
int a=15;
static int b=20;
void A(){
System.out.println(a);
// System.out.println(InnerClass3.a);
}
static void B(){
System.out.println(b);
System.out.println(InnerClass3.b);
}
}
public static void main(String[] args) {
InnerClass3.inner3 inner3=new InnerClass3.inner3();
inner3.A();
InnerClass3.inner3.B();
}
}
匿名内部类
- 匿名内部类比较常见,比如回调函数,将匿名内部类作为方法参数传递。
- 直接使用方法就是
接口 name=new 接口(){[重写接口所有函数]}
。 - 匿名内部类没有构造器。
- 匿名内部类可以访问外部方法的局部变量,但必须是final声明的或者实际不变的。
- 原因是当外部方法结束返回时,内部类对象,方法有可能还在,如果引用的外部的局部变量已经没了,就会发生错误,所以通过final修饰,将局部变量复制一份到内部类中,保证数据的一致性。
public class CallBackUser{
public static void main(String[] args) {
int b=5;
// b=5;
CallBackSystem callBackServer=new CallBackSystem();
callBackServer.onBtnClick("CallBack", new CallBack() {
@Override
public void fun(String name) {
System.out.println("Hello "+name+" "+b);
}
});
}
}
回调函数
考虑一个问题,如何让系统调用你写的一个方法? 比如点击某个按钮就执行你写的方法。
- 我们可以把自己写的函数传给[点击按钮]这个函数,在这个函数里面系统就能调用这个参数(是一个函数),比如Arrays.sort就是一个中间函数,而传进去的匿名内部类(别的语言可以是传递函数指针)就是一个回调函数,sort函数内部就会调用这个compare函数去进行比较,排序。
- 其他语言比如C++/Python可以直接把函数作为另一个函数的参数传入,从而进行回调操作。
在Java中实现一个简单的回调功能需要以下几步:
- 规定一个统一的接口
相当于把要回调的函数封装在这个接口里面,把实现这个接口的匿名内部类传递给调用者(系统)。
public interface CallBack {
void fun(String name);
}
- 系统端写好的API函数
系统写API函数的时候不知道用户具体会传递什么回调函数,只能是根据统一的接口来写代码,所以就调用CallBack类型的参数的对应函数。
public class CallBackSystem {
public void onBtnClick(String name,CallBack callBack){
System.out.println("点击按钮后系统调用你写的方法");
callBack.fun(name);
}
}
- 用户调用系统函数,传入回调函数等待系统回调
这里就用到了匿名内部类,因为系统函数的参数是一个接口类型,所以用户需要一个实现该接口的具体实现类,因为在这里经常需要不同的实现类,所以用匿名内部类是最好的,不需要这个具体的类名。
public class CallBackUser{
public static void main(String[] args) {
CallBackSystem callBackServer=new CallBackSystem();
callBackServer.onBtnClick("CallBack", new CallBack() {
@Override
public void fun(String name) {
System.out.println("Hello "+name);
}
});
}
}
加载全部内容