内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。
内部类可以对同一个包中的其他类隐藏起来。当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
public class Person {
private String id;
private String name;
PersonHandle handler = new PersonHandle();
public Person(String id,String name){
this.id = id;
this.name = name;
}
public void info(){
handler.playInfo();
}
class PersonHandle{
public void playInfo(){
System.out.println(id + " " + name);
}
}
}
使用方法如下:
public static void main(String[] args) {
Person p = new Person("111","bin");
p.info();
//在外部类之外使用内部 类
Person.PersonHandle han = p.new PersonHandle();
han.playInfo();
}局部内部类:
局部类不能用public或private访问说明符进行声明。它的作用域被限定在声明这个局部类的块中。
局部类有一个优势,即对外部可以完成隐藏起来。
局部类可以访问外部类的局部变量,但是那些局部变量必须声明为final。
public class Student {
private String id;
private String name;
public Student(String id,String name){
this.id = id;
this.name = name;
}
public void info(final String password){
class StudentHandle{
public void playInfo(){
System.out.println(id + " " + name + " " + password);
}
}
StudentHandle han = new StudentHandle();
han.playInfo();
}
}使用方法如下:
Student s = new Student("111","bin");
s.info("123");输出结果:111 bin 123
有时,final限制显得并不太方便。补救的方法是使用一个长度为1的数组。(数组变量被声明为final,但是这仅仅表示不可以让它引用另外一个数组。数组中的数据元素可以自由地更改)。
public class Student {
private String id;
private String name;
public Student(String id,String name){
this.id = id;
this.name = name;
}
public void info(final String[] password){
class StudentHandle{
public void playInfo(){
System.out.println(id + " " + name + " " + password[0]);
password[0] += " pass";
}
}
StudentHandle han = new StudentHandle();
han.playInfo();
}
}使用如下:
Student s = new Student("111","bin");
String[] password = new String[]{"123"};
s.info(password);
System.out.println(password[0]);输出结果 :
111 bin 123
123 pass
匿名内部类:
如果只创建内部类的一个对象,就不必命名了,这种类被称为匿名内部类:
如先定义一个接口:
public interface ActionListener {
void process();
}
定义一个接口的调用 类:
public class ActionProcessor {
public void processAction(ActionListener listener){
listener.process();
}
}
可以编写匿名内部类,如下:
ActionProcessor processor = new ActionProcessor();
processor.processAction(new ActionListener() {
public void process() {
System.out.println("处理成功");
}
});由于构造器的名字必须与类名相同,而匿名类没有类名,所以,匿名类不能有构造 器。取而代之,将构造器参数传递给超类构造 器。尤其是在内部类实现接口的时候,不能有任何构造参数。
静态内部类:
如果使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外部类,那么可以把内部类声明为static,以便取消产生的引用。
public class ArrayAlg {
public static Pair getMaxAndMin(double[] values){
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
for(double v : values){
if(min > v)
min = v;
if(max < v)
max = v;
}
return new Pair(min, max);
}
static class Pair{
private double first;
private double second;
public Pair(double f,double s){
first = f;
second = s;
}
public double getFirst(){
return first;
}
public double getSecond(){
return second;
}
}
}如上,getMaxAndMin方法同时返回最大值和最小值,因此将结果会在Pair类中,Pair是一个十分大众化的名字。在大型项目中,除了定义包含一对字符串的Pair类之外,其他程序员也很可能使用这个名字。这样就会使用名字冲突。解决这个问题的办法就是将Pair定义为ArrayAlg的内部公有类。而在Pair对象中不需要引用任何其他的对象,为些,可以将这个内部类声明为static。注意:只有内部类可以声明为static。
在上面例子中,内部类必须定义为静态的,因此它在静态方法中构造 了。
调用方法如下:
ArrayAlg.Pair pair = ArrayAlg.getMaxAndMin(new double[]{12.3,25,56,2.7});
System.out.println(pair.getFirst());
System.out.println(pair.getSecond());
本文详细介绍了Java内部类的使用方法,包括成员内部类、局部内部类、匿名内部类及静态内部类的特点与应用场景。通过具体实例展示了如何在不同场景下应用这些内部类。
924

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



