https://www.cnblogs.com/jtlgb/p/11196380.html
1 內部類
就是定義在另外一個類里面的類。它隱藏在外部類中,封裝性更強,不允許除外部類外的其他類訪問它;但它可直接訪問外部類的成員。
2 靜態內部類
就是定義在另外一個類里面的類。帶static 關鍵字的。
public class OuterClass {
private String sex;
public static String name = "chenssy";
/**
*靜態內部類
*/
static class InnerClass1{
/* 在靜態內部類中可以存在靜態成員 */
public static String _name1 = "chenssy_static";
public void display(){
/*
* 靜態內部類只能訪問外圍類的靜態成員變量和方法
* 不能訪問外圍類的非靜態成員變量和方法
*/
System.out.println("OutClass name :" + name);
}
}
/**
* 內部類
*/
class InnerClass2{
/* 非靜態內部類中不能存在靜態成員 */
public String _name2 = "chenssy_inner";
/* 非靜態內部類中可以調用外圍類的任何成員,不管是靜態的還是非靜態的 */
public void display(){
System.out.println("OuterClass name:" + name);
}
}
/**
* @desc 外圍類方法
* @author chenssy
* @data 2013-10-25
* @return void
*/
public void display(){
/* 外圍類訪問靜態內部類:內部類. */
System.out.println(InnerClass1._name1);
/* 靜態內部類 可以直接創建實例不需要依賴於外圍類 */
new InnerClass1().display();
/* 非靜態內部的創建需要依賴於外圍類 */
OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
/* 方位非靜態內部類的成員需要使用非靜態內部類的實例 */
System.out.println(inner2._name2);
inner2.display();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.display();
}
}
靜態內部類 和內部類 的不同
1.靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。
2.靜態內部類只能訪問外部類的靜態成員變量和靜態方法,而非靜態內部類由於持有對外部類的引用(this),可以訪問外部類的所用成員
3.對象創建的方式不同
靜態內部類無需依賴於外部類,它可以獨立於外部對象而存在,可以和外部類一樣使用 創建方式是注意是new 外部類本身.靜態內部類()。
* b.實例化一個靜態內部類的方法:
* a.不依賴於外部類的實例,直接實例化內部類對象
* OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();
* b.調用內部靜態類的方法或靜態變量,通過類名直接調用
* OutClassTest.InnerStaticClass.static_value
* OutClassTest.InnerStaticClass.getMessage()
內部類創建對象的時候,不能獨立於外部類,必須要先創建外部類的對象,然后再用這個對象來new出內部類的對象 創建方式是 是外部類實例.new 內部類()。
* a.實例化一個非靜態的內部類的方法:
* a.先生成一個外部類對象實例
* OutClassTest oc1 = new OutClassTest();
* b.通過外部類的對象實例生成內部類對象
* OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
使用內部類的好處:
1. 它隱藏在外部類中,封裝性更強,不允許除外部類外的其他類訪問它;但它可直接訪問外部類的成員。
2.也是最吸引人的原因,每個內部類都能獨立地繼承一個接口,而無論外部類是否已經繼承了某個接口。因此,內部類使多重繼承的解決方案變得更加完整。
3 匿名內部類 適合創建那種只需要一次使用的類 。
為啥使用匿名內部類 :比如:現在有一個接口,規范了某些功能,但是在別的類中突然想使用這個功能,但是又只用一次就行了,如果再創建一個類,實現該接口,然后再調用該類,多麻煩啊!舉例:我們創建線程的時候。用匿名內部類創建多線程有兩種方式,就和創建一個線程是一樣的,一種是繼承Thread一種是實現 Runnable接口。就很簡單
https://blog.csdn.net/chengqiuming/article/details/91352913
第一種:
new Thread(){
public void run(){
//你想做的事情
};
}.start();
第二種:
new Thread(new Runnable() {
public void run() {
//你想做的事情
};
}) {
}.start();
注意:
-
匿名內部類必須繼承一個父類,或實現一個接口,但最多只能繼承一個父類,或實現一個接口。
- 由於匿名內部類不能是抽象類,所以匿名內部類必須實現它的抽象父類或接口里包含的所有抽象方法
-
匿名內部類不能定義構造器。由於匿名內部類沒有類名,所以無法定義構造器,但匿名內部類可以初始化塊,可以通過初始化塊來完成構造器需要完成的工作。
- 在Java 8之前,Java要求被局部內部類、匿名內部類訪問的局部變量必須使用final修飾,從Java 8開始這個限制取消了,Java 8更加智能:如果局部變量被匿名內部類訪問,那么該局部變量相對於自動使用了final修飾。
- ·匿名內部類不能定義任何靜態成員、方法和類。、
- ·只能創建匿名內部類的一個實例。
·一個匿名內部類一定是在new的后面,用其隱含實現一個接口或實現一個類。
·因匿名內部類為局部內部類,所以局部內部類的所有限制都對其生效。 - 我們知道 在一個類里如果有內部類,則編譯是會產生多個class文件,一個類class 一個是內部類class(如果有多個內部類就產生多個),匿名內部類也是如此。只是匿名內部類沒有類名,系統會給我們自動賦予名字。MyClass$1.class