转自:http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html
http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html
http://blog.youkuaiyun.com/zhandoushi1982/article/details/8778487
一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。
Java中的内部类共分为四种:
静态内部类static inner class (also called nestedclass)
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class
静态内部类Static Inner Class
最简单的内部类形式。
类定义时加上static关键字。
不能和外部类有相同的名字。
被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。
只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
生成静态内部类对象的方式为:
OuterClass.InnerClassinner = new OuterClass.InnerClass();
静态内部类使用代码:
静态内部类使用测试
packagecom.learnjava.innerclass;
class StaticInner
{
private static int a = 4;
// 静态内部类
public static class Inner
{
public void test()
{
// 静态内部类可以访问外部类的静态成员
// 并且它只能访问静态的
System.out.println(a);
}
}
}
public classStaticInnerClassTest
{
public static void main(String[] args)
{
StaticInner.Inner inner = newStaticInner.Inner();
inner.test();
}
}
成员内部类Member Inner Class
成员内部类也是定义在另一个类中,但是定义时不用static修饰。
成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。
成员内部类就像一个实例变量。
它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。
在外部类里面创建成员内部类的实例:
this.new Innerclass();
在外部类之外创建内部类的实例:
(new Outerclass()).new Innerclass();
在内部类里访问外部类的成员:
Outerclass.this.member
详情见代码例子:
成员内部类使用测试
packagecom.learnjava.innerclass;
class MemberInner
{
private int d = 1;
private int a = 2;
// 定义一个成员内部类
public class Inner2
{
private int a = 8;
public void doSomething()
{
// 直接访问外部类对象
System.out.println(d);
System.out.println(a);// 直接访问a,则访问的是内部类里的a
// 如何访问到外部类里的a呢?
System.out.println(MemberInner.this.a);
}
}
}
public classMemberInnerClassTest
{
public static void main(String[] args)
{
// 创建成员内部类的对象
// 需要先创建外部类的实例
MemberInner.Inner2 inner = newMemberInner().new Inner2();
inner.doSomething();
}
}
局部内部类Local Inner Class
局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。
像局部变量一样,不能被public, protected, private和static修饰。
只能访问方法中定义的final类型的局部变量。
局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
成员内部类使用测试
packagecom.learnjava.innerclass;
class LocalInner
{
int a = 1;
public void doSomething()
{
int b = 2;
final int c = 3;
// 定义一个局部内部类
class Inner3
{
public void test()
{
System.out.println("HelloWorld");
System.out.println(a);
// 不可以访问非final的局部变量
// error: Cannot refer to anon-final variable b inside an inner
// class defined in a differentmethod
// System.out.println(b);
// 可以访问final变量
System.out.println(c);
}
}
// 创建局部内部类的实例并调用方法
new Inner3().test();
}
}
public classLocalInnerClassTest
{
public static void main(String[] args)
{
// 创建外部类对象
LocalInner inner = new LocalInner();
// 调用外部类的方法
inner.doSomething();
}
}
匿名内部类Anonymous Inner Class
匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。
匿名内部类隐式地继承了一个父类或者实现了一个接口。
匿名内部类使用得比较多,通常是作为一个方法参数。
匿名内部类使用测试
packagecom.learnjava.innerclass;
importjava.util.Date;
public classAnonymouseInnerClass
{
@SuppressWarnings("deprecation")
public String getDate(Date date)
{
return date.toLocaleString();
}
public static void main(String[] args)
{
AnonymouseInnerClass test = new AnonymouseInnerClass();
// 打印日期:
String str = test.getDate(new Date());
System.out.println(str);
System.out.println("----------------");
// 使用匿名内部类
String str2 = test.getDate(new Date()
{
});// 使用了花括号,但是不填入内容,执行结果和上面的完全一致
// 生成了一个继承了Date类的子类的对象
System.out.println(str2);
System.out.println("----------------");
// 使用匿名内部类,并且重写父类中的方法
String str3 = test.getDate(new Date()
{
// 重写父类中的方法
@Override
@Deprecated
public String toLocaleString()
{
return "Hello: " +super.toLocaleString();
}
});
System.out.println(str3);
}
}
1. 匿名内部类的基本实现
abstract class Person{
public abstract void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
运行结果:eat something
可以看到,我们直接将抽象类Person中的方法在大括号中实现了
这样便可以省略一个类的书写
并且,匿名内部类还能用于接口上
2. 在接口上使用匿名内部类
interface Person {
public void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eatsomething");
}
};
p.eat();
}
}
运行结果:eat something
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现
最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口
3. 匿名内部类的注意事项
A,匿名内部类不能有构造方法。
B,匿名内部类不能定义任何静态成员、方法和类。
C,匿名内部类不能是public,protected,private,static。
D,只能创建匿名内部类的一个实例。
E,一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
F,因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
G,匿名类和内部类中的中的this:有时候,我们会用到一些内部类和匿名类。当在匿名类中用this时,这个this则指的是匿名类或内部类本身。这时如果我们要使用外部类的方法和变量的话,则应该加上外部类的类名。
4. 匿名内部类实例,在安卓中,典型的也是各种Listener,比如按键的监听
447



被折叠的 条评论
为什么被折叠?



