内部类的分类
内部类分别有成员内部类、局部内部类、匿名内部类、静态内部类。
下面一一介绍:
成员内部类
位置:就是位于外部类成员位置的类。与外部类的属性、方法并列。
- 特点1:成员内部类作为外部类的成员,可以访问外部类的私有成员或属性。即使将外部类的成员或属性声明为private,但是对于成员内部类还是可见的。
- 特点2:用成员内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。 - 作用:数据安全。如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的途径来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方法中增加一些判断语句,起到数据安全的作用。
代码:
public class Demo1 {
public void outf() {
innerclass in=new innerclass();
in.inf(); //因为in是成员内部类的实例化,所以才可以调用
}
class innerclass{//成员内部类
int y=0;
public innerclass() {//成员内部类的构造方法
}
public void inf() {
System.out.println("内部类方法y="+y);
}
}
public static void main(String[] args) {
Demo1 iDemo1=new Demo1();
iDemo1.outf();
Demo1.innerclass j= iDemo1.new innerclass(); //非外部类位置成员内部类实例化的方法(即首先要实例化一个外部类)
Demo1.innerclass k=new Demo1().new innerclass(); //实例化外部类和构造内部类一起写
j.inf();
}
}
结果:
内部类方法y=0
内部类方法y=0
内部类方法y=0
局部内部类
位置:定义在一个方法或者一个作用域里面的类。
- 特点1:局部内部类中不可定义静态变量
- 特点2:可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的;就算没有final修饰,可以访问,但不能修改。
- 特点3:可以访问外部类的所有成员或属性
- 特点4:局部内部类只能在所在的方法体作用域内进行实例化,而如果要在所在方法体返回该类,就要通过接口向上转型的操作。
- 作用:在某些情况下,某些业务逻辑需要临时处理,这些业务逻辑只在这里使用又可以封装成一个类的话,而又没必要重新建个文件,所以可以这写一个局部内部类来处理。然后,在我的记忆中,java代理模式中有用到局部内部类,在方法中直接实现接口,返回代理对象,简单而又方便。
代码:
public class Demo2 {
public outinterface action(String x) {//要把这个类返回出去,就需要通过接口,因为内部类在外部作用域中不存在
class innerclass2 implements Outinterface{
public innerclass2(String s) {
s = x;
System.out.println(s);
}
}
return new innerclass2("do");
}
public static void main(String[] args) {
Demo2 demo2=new Demo2();
Outinterface o = demo2.action("局部内部类");
}
}
interface Outinterface{ //专门用来给局部内部类做向上转型的父接口的操作
}
静态内部类
位置:静态字段的内部类,和静态方法并列。
-特点:只能访问外部类的静态成员。
- 作用:提供调试作用。我将main方法写在静态内部类中,生成.class文件后,调试代码在静态内部类当中,当我删除静态内部类后,其他人仍然可以使用我的外部类。
代码:
public class Demo3 {
static int x=100;
static class innerclass3 {
void action() {
x=1; //x必须是静态字段
}
public static void main(String[] args) {
System.out.println("我是静态内部类");
}
}
}
匿名内部类
- 一个没有名字的类,是内部类的简化写法。
- 本质:其实是继承该类或者实现接口的子类匿名对象。
- 作用:我们在开发的时候,会看到抽象类,或者接口作为参数。而这个时候,实际需要的是一个子类对象。如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
代码1:
//代码示例一
public class Demo4 {
public Outinterface2 action() {
return new Outinterface2() { //②
private int i = 0;
public int getvalue() {
return i;
}
};
}
}
interface Outinterface2 {
}
class innerclass2 implements Outinterface2{//①
private int i = 0;
public int getvalue() {
return i;
}
}
代码2:
//代码示例二
interface Inner {
public abstract void show();
}
class Outer {
public void method(){
new Inner() {
public void show() {
System.out.println("HelloWorld");
}
}.show();
}
}
class Test {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
//如果匿名内部类中有多个方法又该如何调用呢?
Inter i = new Inner() { //多态,因为new Inner(){}代表的是接口的子类对象
public void show() {
System.out.println("HelloWorld");
}
};