Java常用類(1)- 內部類
阿新 • • 發佈:2021-10-25
內部類的概念
概念:在一個類的內部再定義一個完整的類
特點:
//外部類Menber public class Member { private String name; public static void main(String[] args) { new Member().new body().getName(); } //內部類body class body{ public void getName(){ System.out.println(name); } } }
- 編譯之後可以生成獨立的位元組碼檔案
- 內部類可直接訪問外部類的私有屬性,從而不破壞封裝
- 可為外部類提供必要的內部功能元件
內部類的分類
成員內部類
- 在類的內部定義,與例項變數、例項方法同級別的類
- 外部類的一個例項部分,建立內部類物件時,必須依賴外部類物件
package commonclass.innerclass; import java.lang.reflect.Method; //外部類Menber public class Member { //例項變數 private String name; //內部類body publicclass body{ //內部類方法 public void getName(){ System.out.println(name); } } }
import commonclass.innerclass.Member; public class Application { public static void main(String[] args) { //呼叫內部類方法 //方式一 //1.建立外部類物件 Member member = newMember(); //2.建立內部類物件 Member.body body = member.new body(); //方式二 Member.body body1 = new Member().new body(); //方式三直接呼叫 new Member().new body().getName(); //3.呼叫內部類方法 body.getName();//方式一呼叫 body1.getName();//方式二呼叫 } }
- 當外部類、內部類存在重名屬性時,會優先訪問內部類屬性
- 當外部類、內部類存在重名屬性時,想要訪問外部類屬性怎麼辦?外部類.this.外部類屬性
- 成員內部類不能定義靜態成員,但是可以定義靜態常量
靜態內部類
- 不依賴外部類物件,可直接建立或通過類名訪問,可宣告靜態成員
- 只能直接訪問外部類的靜態成員,訪問非靜態成員需要先例項化外部類,再訪問
- 當外部類、靜態內部類存在重名靜態屬性時,想要訪問外部類屬性怎麼辦?外部類.外部類屬性
package commonclass.innerclass; //外部類 public class StaticClass { static String name = "李四"; static int age = 14; double score = 99.9; //靜態內部類,它的級別和外部類一樣; //靜態內部類存在的意義就是供外部類使用 public static class Inner{ //靜態成員 static String name = "張三"; public void getName(){ StaticClass staticClass = new StaticClass(); System.out.println(name); System.out.println(age); System.out.println(staticClass.score); System.out.println(staticClass.name); System.out.println(StaticClass.name); } } }
import commonclass.innerclass.Member; import commonclass.innerclass.StaticClass; public class Application { public static void main(String[] args) { StaticClass.Inner inner = new StaticClass.Inner(); inner.getName(); } }
區域性內部類
- 定義在外部類方法中,作用範圍和建立物件範圍僅限於當前方法
- 區域性內部類訪問外部類當前方法中的區域性變數時,因無法保障變數的生命週期與自動相當(簡單來講就是載入的方法和類載入的問題),方法中的變數必須為常量,jdk1.8之後預設在區域性內部類中,將變數設定為常量
- 使用範圍只有在當前方法中使用
- 區域性內部類方法,最後需要將區域性內部類例項化,在外部類的當前方法中呼叫。區域性內部類才有意義
//外部類 public class LocalClass { //外部類引數 private String name = "張三"; public void print(){ //方法引數 int age = 20; //區域性內部類 class Inner{ //區域性內部類引數 double score = 99.9; //區域性內部類方法 public void show(){ System.out.println(name); System.out.println(age); System.out.println(score); } } //例項化區域性內部類 Inner inner = new Inner(); //呼叫區域性內部類 inner.show(); } }
import commonclass.innerclass.LocalClass; public class Application { public static void main(String[] args) { //區域性內部類只需要new外部類即可,呼叫外部類的方法,從而實現呼叫方法中的區域性內部類 LocalClass localClass = new LocalClass(); localClass.print(); } }
匿名內部類
- 沒有類名的區域性內部類(一切特徵都與區域性內部類相同),可有理解為匿名內部類是區域性內部類的簡寫方式
- 匿名內部類存在的前提是必須繼承一個父類或者實現一個介面
- 定義類、實現類、建立物件的語法合併,只能建立一個該類的物件
- 優點:減少程式碼量
- 缺點:可讀性比較差
前置
package commonclass.innerclass; //介面 public interface UserService { void print(); }
package commonclass.innerclass; //父類 public class Person { public void printFather(){ } }
區域性內部類重寫介面以及父類的方法
package commonclass.innerclass; //外部類 public class AnonymousClass { //main方法 public static void main(String[] args) { //區域性內部類-介面 class UserServiceImp implements UserService{ @Override public void print() { System.out.println("介面重寫"); } } UserServiceImp userServiceImp = new UserServiceImp(); userServiceImp.print(); //區域性內部類-父類 class Student extends Person{ //Alt+Insert選擇Over.. Method重寫父類方法 @Override public void printFather() { System.out.println("繼承父類,父類方法重寫"); super.printFather(); } } Student student = new Student(); student.printFather(); } }
匿名內部類重寫介面以及父類的方法
package commonclass.innerclass; //外部類 public class AnonymousClass { //main方法 public static void main(String[] args) {
//匿名內部類-介面 UserService userService = new UserService(){ @Override public void print() { System.out.println("匿名內部類重寫介面"); } }; userService.print();
//匿名內部類-父類 Person person = new Person(){ @Override public void printFather() { System.out.println("匿名內部類重寫父類方法"); super.printFather(); } }; person.printFather(); } }