内部类,顾名思义,就是在内部定义的类,可以定义在类的内部,也可以定义在方法的内部
java中得内部类分为四种:1、静态内部类,2、成员内部类,3、局部内部类,4、匿名内部类
一、静态内部类 static inner class
静态内部类只能访问外部类静态的属性和方法,只有内部类可以定义为静态的,换言之,一个类如果定义为静态的,必然是内部类
简单的测试类如下,包括了如何定义以及如何使用:
/**
* Created by charleszhu on 14-2-16.
* 测试静态内部类
*/
class StaticInner{
private static int a = 4;
// 定义一个静态内部类
public static class Inner{
// 只能调用静态属性和方法
public void test(){
System.out.println(a);
}
}
}
public class StaticInnerClassTest {
public static void main(String[] args) {
// 创建内部类实例的方法,必须从通过外部类.静态内部类的方式才可以创建
StaticInner.Inner inner = new StaticInner.Inner();
inner.test();
}
}
编译之后,内部类的class文件命名为 StaticInner$Inner.class。
二、成员内部类
调用方式和静态内部类不同,因为是非静态的,所以可以使用非静态的方法和属性
简单测试用例:
/**
* Created by charleszhu on 14-2-16.
* 测试成员内部类
*/
class MemberInner{
private int a = 4;
public class Inner2{
private int a = 5;
public void doSomething(){
// 因为是非静态的,所以可以访问非静态的类
System.out.println("I am invoked!! a=" + a);
//当内部类有与外部类同名的变量,而又想访问外部的变量时;
System.out.println(MemberInner.this.a);
}
}
}
public class MemberInnerClassTest {
public static void main(String[] args) {
//成员内部类的调用和静态内部类的方法有所不同,静态内部类可以通过类名直接调用,因为静态内部类是属于外部类本身的。可以像调用静态方法一样调用
// 而成员内部类是属于对象的,需要new
MemberInner.Inner2 inner2 = new MemberInner().new Inner2();
inner2.doSomething();
}
}
当内部类有与外部类同名的变量,而又想访问外部的变量时,需要从外部类开始访问
System.out.println(MemberInner.this.a);
如果要在外部类中得某个方法创建内部类的实例
Inner2 inner2 = this.new Inner2();//此处不用写作MemberInner.Inner,应为内部可看做同级
/**
* Created by charleszhu on 14-2-17.
*/
class LocalClass{
private int a = 4;
public void test(){
// 定义局部内部类
class Inner3{
final int b= 4;
public void doSomething(){
// 只能访问final类型的变量
System.out.println("LocalInnerClass b=" +4);
}
}
// 内部类无法在外部使用,只能在方法内部定义使用
Inner3 inner3 = new Inner3();
inner3.doSomething();
}
}
public class LocalInnerClassTest {
public static void main(String[] args) {
LocalClass localClass = new LocalClass();
//如此才能让Test方法中的Inner3的doSomeThing执行
localClass.test();
}
}
四 、匿名内部类:是使用最多的一种内部类:是表示一个没有名字的特殊的局部内部类类,所以,没有构造方法,也没有class关键字
但是:匿名内部类会隐士的继承一个类或者实现一个借口,具体实现了什么接口或者继承了什么类,要看test(new Date(){//可以重写父类方法 }),中new之后是什么类或者接口
此处是Date,则生成的匿名内部类就是Date的子类
import java.util.Date;
/**
* Created by charleszhu on 14-2-17.
*/
public class AnonymousInnerClassTest {
public String get(Date date){
return date.toString();
}
public static void main(String[] args) {
AnonymousInnerClassTest test = new AnonymousInnerClassTest();
// 此处做了2件事儿:1定义了一个匿名内部类,2这个内部类继承了Date这个类,所以生成的实例是一个继承自Date类的子类的实例,
// 到底继承了什么或是实现了什么,就看new后面是什么类或者接口
String str = test.get(new Date(){
// 因为这个内部类继承了Date这个类,所以可以重写其中的方法,重写我们要用的方法
@Override
public String toLocaleString() {
return "hello world";
}
});
// 此时结果应该输出的是hello world
System.out.println(str);
}
}
结果输出为:hello world
get(new Date()) 和get(new Date(){ })
是两个完全不同的意思,前者是新建了一个Date对象,传递给了方法
后者是新建了一个继承自Date匿名内部类,并且创建一个对象实例,传给方法。
内部类 在日常开发用的不是很多,但了解,对将来学习框架,阅读别人的代码,无疑是有好处的。