內部類方法可以訪問該類定義所在的作用域中的數據,包括私有的數據。
內部類可以對同一個包中的其他類隱藏起來。當想要定義一個回調函數且不想編寫大量代碼時,使用匿名內部類比較便捷。
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());