標籤:不同的 this 才有 不能 簡潔 nbsp 初始 system for迴圈
參考http://how2j.cn/k/interface-inheritance/interface-inheritance-inner-class/322.html#nowhere
非靜態內部類
非靜態內部類 BattleScore “戰鬥成績”
非靜態內部類可以直接在一個類裡面定義
比如:
戰鬥成績只有在一個英雄對象存在的時候才有意義
所以執行個體化BattleScore 的時候,必須建立在一個存在的英雄的基礎上
文法: new 外部類().new 內部類()
作為Hero的非靜態內部類,是可以直接存取外部類的private執行個體屬性name的
package charactor; public class Hero { private String name; // 姓名 float hp; // 血量 float armor; // 護甲 int moveSpeed; // 移動速度 // 非靜態內部類,只有一個外部類對象存在的時候,才有意義 // 戰鬥成績只有在一個英雄對象存在的時候才有意義 class BattleScore { int kill; int die; int assit; public void legendary() { if (kill >= 8) System.out.println(name + "超神!"); else System.out.println(name + "尚未超神!"); } } public static void main(String[] args) { Hero garen = new Hero(); garen.name = "蓋倫"; // 執行個體化內部類 // BattleScore對象只有在一個英雄對象存在的時候才有意義 // 所以其執行個體化必須建立在一個外部類對象的基礎之上 BattleScore score = garen.new BattleScore(); score.kill = 9; score.legendary(); } }靜態內部類
在一個類裡面聲明一個靜態內部類
比如敵方水晶,當敵方水晶沒有血的時候,己方所有英雄都取得勝利,而不只是某一個具體的英雄取得勝利。
與非靜態內部類不同,靜態內部類水晶類的執行個體化 不需要一個外部類的執行個體為基礎,可以直接執行個體化
文法:new 外部類.靜態內部類();
因為沒有一個外部類的執行個體,所以在靜態內部類裡面不可以訪問外部類的執行個體屬性和方法
除了可以訪問外部類的私人靜態成員外,靜態內部類和普通類沒什麼大的區別
package charactor; public class Hero { public String name; protected float hp; private static void battleWin(){ System.out.println("battle win"); } //敵方的水晶 static class EnemyCrystal{ int hp=5000; //如果水晶的血量為0,則宣布勝利 public void checkIfVictory(){ if(hp==0){ Hero.battleWin(); //靜態內部類不能直接存取外部類的對象屬性 System.out.println(name + " win this game"); } } } public static void main(String[] args) { //執行個體化靜態內部類 Hero.EnemyCrystal crystal = new Hero.EnemyCrystal(); crystal.checkIfVictory(); } }匿名類
匿名類指的是在聲明一個類的同時執行個體化它,使代碼更加簡潔精練
通常情況下,要使用一個介面或者抽象類別,都必須建立一個子類
有的時候,為了快速使用,直接執行個體化一個抽象類別,並“當場”實現其抽象方法。
既然實現了抽象方法,那麼就是一個新的類,只是這個類,沒有命名。
這樣的類,叫做匿名類 另一篇匿名類講解
package charactor; public abstract class Hero { String name; //姓名 float hp; //血量 float armor; //護甲 int moveSpeed; //移動速度 public abstract void attack(); public static void main(String[] args) { ADHero adh=new ADHero(); //通過列印adh,可以看到adh這個對象屬於ADHero類 adh.attack(); System.out.println(adh); Hero h = new Hero(){ //當場實現attack方法 public void attack() { System.out.println("新的進攻手段"); } }; h.attack(); //通過列印h,可以看到h這個對象屬於Hero$1這麼一個系統自動分配的類名 System.out.println(h); } }本地類
本地類可以理解為有名字的匿名類
與內部類不一樣的是,內部類必須聲明在成員的位置,即與屬性和方法平等的位置。
本地類和匿名類一樣,直接聲明在代碼塊裡面,可以是主方法,for迴圈裡等等地方
package charactor; public abstract class Hero { String name; //姓名 float hp; //血量 float armor; //護甲 int moveSpeed; //移動速度 public abstract void attack(); public static void main(String[] args) { //與匿名類的區別在於,本地類有了自訂的類名 class SomeHero extends Hero{ public void attack() { System.out.println( name+ " 新的進攻手段"); } } SomeHero h =new SomeHero(); h.name ="地蔔師"; h.attack(); } }在匿名類中使用外部的局部變數
在匿名類中使用外部的局部變數,外部的局部變數必須修飾為final
為什麼要聲明為final,其機制比較複雜,請參考第二個Hero代碼中的解釋
註:在jdk8中,已經不需要強制修飾成final了,如果沒有寫final,不會報錯,因為編譯器偷偷的幫你加上了看不見的final
Hero.java代碼
package charactor; public abstract class Hero { public abstract void attack(); public static void main(String[] args) { //在匿名類中使用外部的局部變數,外部的局部變數必須修飾為final final int damage = 5; Hero h = new Hero(){ public void attack() { System.out.printf("新的進攻手段,造成%d點傷害",damage ); } }; } }
abstract Hero代碼
package charactor; public abstract class Hero { public abstract void attack(); public static void main(String[] args) { //在匿名類中使用外部的局部變數damage 必須修飾為final int damage = 5; //這裡使用本地類AnonymousHero來類比匿名類的隱藏屬性機制 //事實上的匿名類,會在匿名類裡聲明一個damage屬性,並且使用構造方法初始化該屬性的值 //在attack中使用的damage,真正使用的是這個內部damage,而非外部damage //假設外部屬性不需要聲明為final //那麼在attack中修改damage的值,就會被暗示為修改了外部變數damage的值 //但是他們倆是不同的變數,是不可能修改外部變數damage的 //所以為了避免產生誤導,外部的damage必須聲明為final,"看上去"就不能修改了 class AnonymousHero extends Hero{ int damage; public AnonymousHero(int damage){ this.damage = damage; } public void attack() { damage = 10; System.out.printf("新的進攻手段,造成%d點傷害",this.damage ); } } Hero h = new AnonymousHero(damage); } }
java 內部類詳解