初識java內部類
內部類:指的是在Java中可以將一個類定義在另一個類的內部。
- 內部類可以定義在 類的內部 (與類成員層次一致)
- 內部類可以定義在 方法/塊內部 (與類成員相差一個層次,與方法的局部變量是一個層次)
*1.成員內部類
將一個類直接定義在類的裏面,作爲成員,與屬性或方法層次一致。
成員內部類可以與正常類一樣 使用不同的修飾符(權限的 ,特徵的都行)來修飾
外部類只能使用兩種權限修飾符,(public ,默認不寫)
而內部類可以使用全部的四種權限修飾符,(public, protected ,默認不寫 ,private)
好處1.省略了一個.java源文件
好處2.成員內部類中可以訪問外部類的所有成員 ,包括私有的
public class Demo {
private String name = "這是正常類中的屬性";
public void testDemo(){
System.out.println("這是正常類中的方法");
}
//成員內部類
public class InnerDemo{
public void testInnerDemo(){
System.out.println("我是成員內部類的方法"+name);
testDemo();
}
}
}
public static void main(String[] args) {
//創建內部類的對象---調用內部類的方法
Demo.InnerDemo innerDemo = new Demo().new InnerDemo();
//調用內部類的方法
innerDemo.testInnerDemo();
}
輸出結果:
若想要在內部類中通過對象.的方式調用外部類成員,方式爲: 外部類.this.外部類成員;
public class Demo {
private String name = "這是正常類中的屬性";
public void testDemo(){
System.out.println("這是正常類中的testDemo方法");
}
//成員內部類
public class InnerDemo{
private String name = "我是內部類的屬性";
public void testDemo(){
System.out.println("這是內部類中的testDemo方法");
}
public void testInnerDemo(){
System.out.println("我是成員內部類的testInnerDemo方法:"+name);//這個name就是內部類的
//如果想要訪問外部類的name屬性,應該這樣寫:
System.out.println("我是成員內部類的方法:"+Demo.this.name);
testDemo();
Demo.this.testDemo();
}
}
}
public static void main(String[] args) {
//創建內部類的對象---調用內部類的方法
Demo.InnerDemo innerDemo = new Demo().new InnerDemo();
//調用內部類的方法
innerDemo.testInnerDemo();
}
輸出結果:
內部類存在後 源代碼進行編譯 產生一個字節碼 Demo$InnerDemo.class
我們可以看出,美元符號
其實就是內部類命名的標誌。
2.局部內部類
將一個類定義在方法/塊裏面,作爲成員的內部結構,與臨時的局部變量一個層次。
局部內部類是臨時存在的,方法執行完,這個類的空間就被自動回收了。
局部內部類像是一個局部的變量一樣,不能用public protected private及static
只能用abstract或final。
【小技巧】:在類中寫一個空的main函數,讓它去執行, 可以讓該類立即被編譯,生成.class文件。
局部內部類命名規則:
Demo$1InnerTestOneDemo
Demo$2InnerTestOneDemo
出現內部類重名以後,會有數字將它們區分開,1
表示第1次出現的內部類,2
表示第2次出現的內部類。
public class Demo {
private String name = "這是正常類中的屬性";
public void testDemo(){
System.out.println("這是正常類中的testDemo方法");
}
public void testDemoOne(){
String s = "abc";
//在方法中定義一個局部內部類
class InnerTestOneDemo{
//局部內部類使用的變量都需要加final來修飾
}
}
{
//在塊中定義一個局部內部類,與方法中那個內部類重名了
class InnerTestOneDemo{
//局部內部類使用的變量都需要加final來修飾
}
}
}
*局部內部類使用的變量只能是final修飾,爲什麼?
因爲局部內部類是類加載的時候就編譯好了,編譯好的.class文件是不能改變的,如果局部內部類中的變量不使用final修飾,讓變量隨意去改變,就會產生衝突。
*3.匿名內部類
成員匿名內部類
局部匿名內部類
不用匿名內部類,以前我們這樣寫:
public interface Test {
public void test();
}
public class Son implements Test{
@Override
public void test() {
//······
}
}
public static void main(String[] args) {
Test t = new Son();
t.test();
}
有了匿名內部類以後,我們可以這樣寫:
public interface Test {
public void test();
}
public static void main(String[] args) {
Test t = new Test(){
public void test() {
//······
}
};//分號不可省略
}
new Test()後面的大括號裏放的是匿名內部類的所有類成員。
通常接口或抽象類的具體子類這樣寫。
開發中爲了省略一個類文件 , 上述寫法比較常見。
匿名內部類很特殊, 只有類體, 沒有類的( 修飾符 名字 繼承 實現)。
不能用任何修飾符來修飾, 匿名內部類也沒有構造方法。
應用:Swing 做一個按鈕 ,綁定一個事件監聽器
4.靜態內部類
成員靜態內部類
不需要外部類對象,通過正常的方式直接創建內部類即可!(前提是先導好包)
靜態元素不能訪問非靜態成員(自己類和外部類的非靜態成員都不行)。
public class Demo {
//靜態內部類
public static class InnerDemoStatic{
}
}
package innerclass;
import innerclass.Demo.InnerDemoStatic;
public class TestMain {
public static void main(String[] args) {
InnerDemoStatic innerStatic = new InnerDemoStatic();
}
}