一、什麼是嵌套類及內部類? 二、靜態嵌套類 |
|
|
public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";
static class Person{
private String address = "swjtu,chenDu,China";
public String mail = "[email protected]";//內部類公有成員
public void display(){
//System.out.println(id);//不能直接訪問外部類的非靜態成員
System.out.println(name);//只能直接訪問外部類的靜態成員
System.out.println("Inner "+address);//訪問本內部類成員。
}
}
public void printInfo(){
Person person = new Person();
person.display();
//System.out.println(mail);//不可訪問
//System.out.println(address);//不可訪問
System.out.println(person.address);//可以訪問內部類的私有成員
System.out.println(person.mail);//可以訪問內部類的公有成員
}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
若想訪問外部類的變量,必須通過其它方法解決,由於這個原因,靜態嵌套類使用很少。注意,外部類訪問內
部類的的成員有些特別,不能直接訪問,但可以通過內部類實例來訪問,這是因爲靜態嵌套內的所有成員和方法默認爲
靜態的了。同時注意,內部靜態類Person只在類StaticTest 範圍內可見,若在其它類中引用或初始化,均是錯誤的。
三、在外部類中定義內部類
如下所示代碼爲在外部類中定義兩個內部類及它們的調用關係:
class Outer{ int outer_x = 100; private class Inner{//私有的內部類 public int y = 10; private int z = 9; int m = 5; public void display(){ System.out.println("display outer_x:"+ outer_x); } private void display2(){ System.out.println("display outer_x:"+ outer_x); } } public Inner getInner(){//即使是對外公開的方法,外部類也無法調用 return new Inner(); } void test(){ Inner inner = new Inner(); //可以訪問 inner.display(); inner.display2(); //System.out.println("Inner y:" + y);//不能訪問內部內變量 System.out.println("Inner y:" + inner.y);//可以訪問 System.out.println("Inner z:" + inner.z);//可以訪問 System.out.println("Inner m:" + inner.m);//可以訪問 InnerTwo innerTwo = new InnerTwo(); innerTwo.show(); } class InnerTwo{ Inner innerx = getInner();//可以訪問 public void show(){ //System.out.println(y);//不可訪問Innter的y成員 //System.out.println(Inner.y);//不可直接訪問Inner的任何成員和方法 innerx.display();//可以訪問 innerx.display2();//可以訪問 System.out.println(innerx.y);//可以訪問 System.out.println(innerx.z);//可以訪問 System.out.println(innerx.m);//可以訪問 } } } public class Test { public static void main(String args[]){ Outer outer = new Outer(); // Outer.Inner a=outer.getInner();//Inner類是私有的,外部類不能訪問,如果Inner類是public ,則可以。 outer.test(); } }
中的方法,不可直接訪問內部類的變量。
四、在方法中定義內部類
如下所示代碼爲在方法內部定義一個內部類:
public class FunOuter { int out_x = 100; public void test(){ class Inner{ String x = "x"; void display(){ System.out.println(out_x); } } Inner inner = new Inner(); inner.display(); } public void showStr(String str){ //public String str1 = "test Inner";//不可定義,只允許final修飾 //static String str4 = "static Str";//不可定義,只允許final修飾 String str2 = "test Inner"; final String str3 = "final Str"; class InnerTwo{ public void testPrint(){ System.out.println(out_x);//可直接訪問外部類的變量 //System.out.println(str);//不可訪問本方法內部的非final變量 //System.out.println(str2);//不可訪問本方法內部的非final變量 System.out.println(str3);//只可訪問本方法的final型變量成員 } } InnerTwo innerTwo = new InnerTwo(); innerTwo.testPrint(); } public void use(){ //Inner innerObj = new Inner();//此時Inner己不可見了。 //System.out.println(Inner.x);//此時Inner己不可見了。 } public static void main(String[] args) { FunOuter outer = new FunOuter(); outer.test(); } }
從上面的例程我們可以看出定義在方法內部的內部類的可見性更小,它只在方法內部 可見,在外部類(及外部類的其它方法中)中都不可見了。同時,它有一個特點,就是方法內的內部類連本方法的成員變量都不可訪問,它只能訪問本方法的final型成員。同時另一個需引起注意的是方法內部定義成員,只允許final修飾或不加修飾符,其它像static等均不可用。
五、匿名內部類
如下所示代碼爲定義一個匿名內部類:匿名內部類通常用在Java的事件處理上
import java.applet.*;
import java.awt.event.*;
public class AnonymousInnerClassDemo extends Applet{
public void init(){
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent me){
showStatus("Mouse Pressed!");
}
});
}
public void showStatus(String str){
System.out.println(str);
}
}
在上面的例子中,方法addMouseListener接受一個對象型的參數表達式,於是,在參數裏,我們定義了一個匿名內部類,這個類是一個MouseAdapter類型的類,同時在這個類中定義了一個繼承的方法mousePressed,整個類做爲一個參數。這個類沒有名稱,但是當執行這個表達式時它被自動實例化。同時因爲,這個匿名內部類是定義在AnonymousInnerClassDemo 類內部的,所以它可以訪問它的方法showStatus。這同前面的內部類是一致的。
六、內部類使用的其它的問題
通過以上,我們可以清楚地看出內部類的一些使用方法,同時,在許多時候,內部類是在如Java的事件處理、或做爲值對象來使用的。同時,我們需注意最後一個問題,那就是,內部類同其它類一樣被定義,同樣它也可以繼承外部其它包的類和實現外部其它地方的接口。同樣它也可以繼承同一層次的其它的內部類,甚至可以繼承外部類本身。下面我們給出最後一個例子做爲結束:
public class Layer { //Layer類的成員變量 private String testStr = "testStr"; //Person類,基類 class Person{ String name; Email email; public void setName(String nameStr){ this.name = nameStr; } public String getName(){ return this.name; } public void setEmail(Email emailObj){ this.email = emailObj; } public String getEmail(){ return this.email.getMailStr(); } //內部類的內部類,多層內部類 class Email{ String mailID; String mailNetAddress; Email(String mailId,String mailNetAddress){ this.mailID = mailId; this.mailNetAddress = mailNetAddress; } String getMailStr(){ return this.mailID +"@"+this.mailNetAddress; } } } //另一個內部類繼承外部類本身 class ChildLayer extends Layer{ void print(){ System.out.println(super.testStr);//訪問父類的成員變量 } } //另個內部類繼承內部類Person class OfficePerson extends Person{ void show(){ System.out.println(name); System.out.println(getEmail()); } } //外部類的測試方法 public void testFunction(){ //測試第一個內部類 ChildLayer childLayer = new ChildLayer(); childLayer.print(); //測試第二個內部類 OfficePerson officePerson = new OfficePerson(); officePerson.setName("abner chai"); //注意此處,必須用對象.new 出來對象的子類對象 //而不是Person.new Email(...) //也不是new Person.Email(...) officePerson.setEmail(officePerson.new Email("josserchai","yahoo.com")); officePerson.show(); } public static void main(String[] args) { Layer layer = new Layer(); layer.testFunction(); } }