內部類就是指在一個類的內部去定義一個類,舉個例子就是人的身體相當於一個外部類,它有自己的各種器官(相當於各種成員、屬性),心臟相當於內部類,當然它也有自己的屬性和行爲,心臟可以通過血管通往人體的各個器官,就好像內部類可以訪問外部類的成員一樣。
內部類的屬性
- 類名稱只能用在定義過的範圍中,除非用限定的名稱來引用它。
- 內部類的名稱必須與所嵌套的類不同。
- 內部類可以使用所嵌套類的成員變量。
- 內部類可以被定義在方法體中。此時,任何變量,不論是局部變量還是正式參數,如果變量被標記爲final,那麼,就可以被內部類中的方法訪問。
- 內部類可以被定義爲abstract。
只有內部類可以被聲明爲private或protected,以便防護它們不受來自外部類的訪問。訪問protected不妨礙內部類使用其它類的任何成員,只要一個類嵌套另一個。
內部類的基本結構
//外部類
class out{
private int number = 10;
//內部類
class In{
public void print(){
System.out.println(number);
}
}
}
public class Test{
public static void main(String[] args){
Out.In in = new Out().new In();
in.print();
}
}
//運行結果爲:10
從上述代碼我們可以看出內部類可以隨意的使用外部類的成員變量(包括私有)而不用生成外部類的對象,這是內部類的優點,程序編譯過後會產生兩個.class文件,分別是Out.class和Out$In.class,$代表Out.in中的點.號,必須先有外部類的對象才能生成內部類的對象,因爲內部類的對象的作用就是爲了訪問外部類中的成員變量。
內部類的變量訪問形式
class Out{
private int num = 10;
class In{
private int num = 20;
public void print(){
int num = 30;
System.out.println("局部變量:"+num);
System.out.println("內部變量:"+this.num);
System.out.println("外部變量:"+Out.this.num);
}
}
}
public class TestClass {
public static void main(String[] args) {
Out.In in = new Out().new In();
in.print();
}
}
//運行結果爲:
//局部變量:30
//內部變量:20
//外部變量:10
從上面兩個例子可以看出當內部類在沒有同名的成員變量和局部變量的情況下,內部類會直接訪問外部類的成員變量,否則內部類中的局部變量會覆蓋外部類的成員變量,而訪問內部類本身的成員變量可用this.屬性名,訪問外部類的成員變量需要使用Out.this.屬性名。
靜態內部類
- 被自動地聲明爲static的內部類成爲嵌套類。這些內部類失去了在局部範圍和其它嵌套類中使用數據或變量的能力。
- 內部類不能聲明任何static成員;只有嵌套類可以聲明static成員。因此,一個需求static成員的內部類必須使用來自嵌套類的成員。
class Out{
private static int num2 = 10;
static class In{
private int num = 20;
public void print(){
int num = 30;
System.out.println("局部變量:"+num);
System.out.println("內部變量:"+this.num);
System.out.println("外部變量:"+num2);
}
}
}
public class TestClass {
public static void main(String[] args) {
Out.In in = new Out.In();
in.print();
}
}
//結果:
局部變量:30
內部變量:20
外部變量:10
靜態內部類只能訪問外部類的靜態成員變量。
私有內部類
如果一個內部類只希望被外部類中的方法所操作,那麼可以使用private將其聲明爲內部類。
class Out{
private static int num = 10;
private class In{
public void inPrint(){
System.out.println(num);
}
}
public void outPrint(){
new In().inPrint();
}
}
public class TestClass {
public static void main(String[] args) {
Out out = new Out();
out.outPrint();
}
}
//運行結果:10
在上面的代碼中我們只能通過外部類裏面來生成內部類的對象來進行操作,而無法直接new出內部類對象,這樣內部類只有外部類可控制。
方法內部類
class Out{
private static int a = 10;
public void outPrint(final int b){
class In{
public void inPrint(){
System.out.println(a);
System.out.println(b);
}
}
new In().inPrint();
}
}
public class TestClass {
public static void main(String[] args) {
Out out = new Out();
out.outPrint(3);
}
}
//運行結果爲:
10
3
匿名類
匿名類就是沒有名字的類。
匿名類只能使用一次,它通常用來簡化代碼的編寫。
使用匿名類的前提是:必須繼承一個父類或實現一個接口
不使用匿名類來實現抽象方法:
abstract class Father{
public abstract void say();
}
class Son extends Father{
@Override
public void say() {
System.out.println("hello");
}
}
public class Test2 {
public static void main(String[] args) {
Father f = new Son();
f.say();
}
}
//結果:hello
使用內部類:
abstract class Father{
public abstract void say();
}
public class Test2 {
public static void main(String[] args) {
Father f = new Father(){
public void say(){
System.out.println("hello");
}
};
f.say();
}
}
//結果:hello
匿名類不具有構造器,Java會暗中調用其超類的構造器。
如果有一個簡單的類,其代碼易懂,並且你熟悉其所處的上下文,那匿名類是個很好的選擇。
在Java中,匿名類經常被用於執行用戶接口的簡單事件處理。
f.addWindowListener(
new WindowAdapter()
{
Public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
“`