以前Android开发的时候,有时候会看到内部类比如定义Adapter的ViewHolder和匿名内部类比如各种事件等。但是对于内部类与匿名内部类的概念以及里面的一些细节却比较模糊,如今我总结如下:
概念
内部类是定义在类中的类。内部类的主要作用是将逻辑上相关的类放到一起。
匿名类是特殊的内部类,没有类名。在定义类的同时,就生成该类的一个实例,并且不会在其他地方用到该类,所以不用起名字,因而又称匿名内部类。
内部类
内部类可以看作是外部类的一个成员,与一般类相同,内部类可以拥有自己的成员变量与成员方法,通过建立内部类对象,可以访问其成员变量和调用成员方法。下面具体看一个简单的实例:
public class Person {
private String name;
// 内部类
public class Student {
private String sex;
public Student(String n, String sex) {
name = n; //赋值给外部类成员变量,所以可以将内部类看作是外部类的一个成员
this.sex = sex;
}
public void output() {
System.out.println("学生姓名是:" +name + " " + "学生性别是:" + sex);
}
}
//外部类方法中调用内部类方法,可以发现内部类方法与外部类方法可以相同。
public void output() {
Student s = new Student("张三", "男");
s.output();
}
public static void main(String[] args) {
//外部类直接调用内部类方法
// Person p = new Person();
// Person.Student s=p.new Student("张三", "男");
// s.output();//内部类的方法
// System.out.println(s.sex);//访问内部类成员变量
//外部类方法中实现对内部类的方法调用
Person p=new Person();
p.output();
}
}
分析:其实在内部类对象中保存了一个对外部类对象的引用,当在内部类的成员方法中访问某一变量时,如果在该方法和内部类中都没有定义过这个变量,(如果有这个变量的话,或者外部类的某个成员变量与内部类的成员变量相同,eg:在内部类中定义private String name; 那么访问的则是内部类的这个变量)调用就会被传递给内部类中的那个对外部类对象的引用,通过这个引用去调用这个变量。在内部类调用外部类的方法也是同样的一个道理(还是这个内部类对象保存了一个对外部类的引用)。
内部类总结: 内部类可以声明成private或protected,访问原则是,在外部类中,通过一个内部类的对象引用内部类中的成员;而在内部类中,可以直接引用外部类的成员。包括静态成员、实例成员、私有成员。当然,内部类也可以通过创建对象从外部类之外被调用,但是内部类必须声明成public的。
注意:内部类如果被声明成static,则静态内部类将自动转化为“顶层类”,即它没有父类,而且不能引用外部类成员或其他内部类中的成员。非静态内部类不能声明静态成员,只有静态内部类才能声明静态成员。
匿名内部类
创建匿名内部类的用意:主要是用来弥补内部类中没有定义到的方法,并能有效的简化程序代码。
public class NoPerson {
public static void main(String[] args) {
new Inner() {
void setName(String n) {
name = n;
System.out.println("姓名是:" + name);
}
}.setName("张三");
}
static class Inner {
String name;
}
}
匿名内部类通常用来编写“事件”的程序代码。