Java内部类
大部分时间类被定义为一个独立的程序单元,但是在某些情况下,也会把一个类放在另一个类的内部定义,这个定义在另一个类内部的类被称为内部类
主要作用:
- 内部类提供了更好的封装,可以把内部类隐藏在外部类里面,不允许同一个包中其他类访问。例如:创建一个Cow类,Cow类需要组合一个CowLeg类,CowLeg类只能通过Cow类访问,离开Cow类之后CowLeg类没有任何意义。
- 内部类成员可以直接访问外部类的私有数据。
- 匿名内部类适用于那些仅需一次使用的类。
-
非静态内部类
大部分时候内部类内部类都被作为成员内部类定义,而不是作为局部内部类。成员内部类是一种与成员变量,方法,构造器和初始化块相似的类成员;局部内部类和匿名内部则不是类成员。
内部类作为外部类的成员,可以使用人访问控制符:private,protect,public等修饰。
class Outer {
private String info = "helloworld";
class Inner{
private String info = "世界,你好";
public void print() {
/*
当外部类成员变量,内部类成员变量与内部类方法里的局部变量同名时,则可以通过this,外部
类.this作为限定区分
*/
System.out.println(Outer.this.info);
}
}
public void getInfo() {
new Inner().print();
System.out.println(new Inner().info);
}
}
public class TestDemo {
public static void main(String[] args) {
//当内部类使用private修饰时,无法实例化内部类
Outer.Inner outer = new Outer().new Inner();
outer.print();
Outer inner = new Outer();
inner.getInfo();
}
}
结果:
helloworld
helloworld
世界,你好
PS:Java不允许外部类的静态成员直接使用非静态内部类,也不允许非晶态内部类里面定义静态成员!
-
静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。因此使用static修饰的内部类被称为类内部类,也被称为静态内部类。
一个静态内部内只能访问外部内中定义的static操作。
public class Demo {
private int a = 5;
private static int b = 7;
static class Inner{
//静态内部类可以包含成员静态变量
private static int age;
public void print() {
//静态内部类无法访问外部类的非static成员下面代码出现错误
System.out.println(a);
System.out.println(b);
}
}
public static void main(String[] args) {
//静态内部类的实例化
Demo.Inner de = new Demo.Inner();
}
}
-
局部内部类
如果把一个类放在方法里面定义,那么这个类就是一个局部内部类,局部内部类仅在方法里面有效。由于局部内部类不能放在外部类的方法以外使用,因此局部内部类不能使用访问控制符和static修饰符修饰。
class TestOuter {
private String info = "helloworld";
/*
JDK1.7以及之前版本中,方法定义的内部类如果想访问方法的参数或者是方法定义的变量,那么参数或变量之前一定套加上“final”标记。
*/
public void fun(final int num) {
final String myinfo = "my love";
class Inner{
public void print() {
System.out.print(TestOuter.this.info+" ");
System.out.println(myinfo);
System.out.println(num);
}
}
new Inner().print();
}
}
public class TestDemo3 {
public static void main(String[] args) {
new TestOuter().fun(100);;
}
}
结果:
helloworld my love
100
-
匿名内部类
匿名内部类适合创建那种只需要使用一次的类。
格式:
new 实现接口()| 父类构造器(实参列表)
{
//匿名内部类的类体部分
}
规则:
1.匿名内部类不能是抽象类,因为系统创建匿名内部类时会立即创建内部类的对象。因此不能将匿名内部类定义成抽象类。
2.匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义初始化块,可以实例化初始块来完成构造器需要完成的事。
interface Message{
public void print();
}
public class TestDemo {
public static void main(String[] args) {
fun(new Message() {
public void print() {
System.out.println("Hello World");
}
});
}
public static void fun(Message msg) {
msg.print();
}
}
结果:
Hello World