系列文章目录
java必知必会-java环境搭建
java必知必会-java开发工具安装与使用
java必知必会-java关键字、变量和常量
java必知必会-java数据类型和变量定义
java必知必会-java类和对象
java必知必会-java面向对象的三大特性
java必知必会-java继承与重写、重载
java必知必会-java构造方法与访问修饰符
java必知必会-java抽象类与接口
java必知必会-java常见关键字及其作用
前言
本文介绍java中的内部类
一、什么是内部类?
- 内部类是指在一个类的内部再定义一个类。
二、内部类的优缺点
- 优点
- 一个内部类对象可以访问创建它的外部类对象的所有成员
- 内部类不为同一包的其他类所见,封装性好
- 每个内部类可以各自继承类和实现接口,实现’多重继承’
- 匿名内部类可以定义回调
- 缺点
- 耦合性增加
- 可读性降低
三、应用场景
- 一些多算法场合;
- 解决一些非面向对象的语句块;
- 当某个类除了它的外部类,不再被其他的类使用时
四、内部类定义
- 内部类分为普通内部类、静态内部类、静态方法内部类,普通方法内部类四种,示例代码如下
//非静态内部类不能定义静态属性和方法
public class Outer {
private int a = 1;
private static int b = 2;
private static void outf1(){System.out.println("outf1");}
private void outf2(){System.out.println("outf2");}
//成员内部类:定义在类内部非静态类。内部类中不能定义静态成员
class Inner {
private int a = 3;
//private static int b = 4; //内部类中不允许定义静态变量和方法
public void inner() {
System.out.println(a);//3 =this.a
System.out.println(b);//2 =this.b;//内部类中不允许定义静态变量
//System.out.println(Outer.a);//不能Outer.a访问外部非静态成员
System.out.println(Outer.b);//2
System.out.println(Outer.this.a);//1
System.out.println(Outer.this.b);//2
outf1();//=Outer.this.outf1();
outf2();//=Outer.this.outf2();
}
}
//静态内部类(nested class):定义在类内部的静态类,不可访问外部类的非静态方法
static class StaticInner {
private int a = 3;
private static int b = 4;
public void inner() {
System.out.println(a);//3 =this.a
System.out.println(b);//4 =this.b;
//System.out.println(Outer.a);//不能Outer.a访问外部非静态成员
System.out.println(Outer.b);//2
//System.out.println(Outer.this.a);//静态内部类不能访问this
//System.out.println(Outer.this.b);//静态内部类不能访问this
outf1();//Outer.this.outf1();//静态内部类不能访问this
//outf2();//静态内部类不能访问非静态方法 Outer.this.outf2();静态内部类不能访问this
}
}
//局部内部类:定义在方法中的内部类。可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法,不能创建静态变量
public static void outf3(){
class Inner {
private int a = 3;
//private static int b = 4;//不允许静态
public void inner() {
System.out.println(a);//3 =this.a
System.out.println(b);//2 =this.b//不允许静态
//System.out.println(Outer.a);//不能Outer.a访问外部非静态成员
System.out.println(Outer.b);
//System.out.println(Outer.this.a);//静态方法内部类不能访问this
//System.out.println(Outer.this.b);//静态方法内部类不能访问this
outf1(); //Outer.this.outf1(); 静态方法内部类不能访问this
//outf2();//静态内部类不能访问非静态方法 Outer.this.outf2();静态方法内部类不能访问this
}
}
}
public void outf4(){
class Inner {
private int a = 3;
//private static int b = 4;//不允许静态
public void inner() {
System.out.println(a);//3 = this.a
System.out.println(b);//2 = this.b 不允许静态
//System.out.println(Outer.a);//不能Outer.a访问外部非静态成员
System.out.println(Outer.b);
System.out.println(Outer.this.a);
System.out.println(Outer.this.b);
outf1();// = Outer.this.outf1();
outf2();// = Outer.this.outf2();
}
}
}
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();//外部类名.内部类名 变量名 = new 外部类名().new 内部类名();
inner.inner();
Outer.StaticInner staticInner = new Outer.StaticInner();//静态内部类的创建方式,new 外部类.静态内部类()
staticInner.inner();
Outer outer = new Outer();
Outer.outf3();
outer.outf4();
}
}
访问私有构造,私有方法和私有属性都要setAccessible(true)才能使用
四、匿名内部类
- 匿名内部类: 没有名字的内部类,不能是抽象的必须继承一个抽象类或者实现一个接口所有抽象方法。不能定义任何静态成员和静态方法。
- 当所在的方法的形参需要被匿名内部类使用时,必须声明为final?
- 因为生命周期不一致,局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题
- 临时定义某一指定类型的子类并创建刚刚定义的这个子类的对象
- 当所在的方法的形参需要被匿名内部类使用时,必须声明为final?
public class Outer {
public void fun(Service service){//方法回调
service.method();
}
public static void main(String[] args){
Outer outer = new Outer();
outer.fun(
new Service() {
public void method() { System.out.println("匿名内部类" ); }
}
);
}
}
interface Service{//匿名内部类必须继承或实现一个已有的接口
void method();
}
五、内部类的继承
- 内部类的继承,父子类的内部类不能覆盖,只能继承
public class InheritInner extends Outer.Inner {
InheritInner(Outer outer){
outer.super();
}
public static void main(String[] args) {
Outer outer = new Outer();
InheritInner inheritInner = new InheritInner(outer);
}
}
class Outer{
class Inner{}
}
总结
本文介绍了java的内部类,如果有任何疑问欢迎私信或者评论