java基礎第二十四課---java內部類
內部類是一個定義在另一個類中的類。那為什麼要使用內部類呢?其主要原因有以下三點
藉助於內部類可以實現類似於多繼承的作用1.內部類方法可以訪問該類定義所在的作用域中的資料,包括私有資料
2.內部類可以對統一包中的其他資料隱藏起來,增強面向物件的封裝性
3.當想定義一個回撥函式且不想編寫大量程式碼時,使用匿名內部類比較便捷
public class Person {
//人在出生的時候選擇性別
private String[] sex = {"男性","女性"};
class Xiaoming{
private String xiaoming_sex;
private String showSex() {
// TODO Auto-generated method stub
xiaoming_sex = sex[1];
return xiaoming_sex;
}
}
//在外部類當中定義一個方法展示小明的性別
private void show_XiaoMing_sex() {
// TODO Auto-generated method stub
Xiaoming xiaoming = new Xiaoming();
System.out.println(xiaoming. showSex());
}
public static void main(String[] args) {
Person person = new Person();
person.show_XiaoMing_sex();
}
}
為了能夠執行程式,內部類的物件總有一個隱式引用,他指向了建立他的外部類物件
內部類物件擁有一個對外圍外部類物件的引用
請注意一下,outer不是java關鍵字,我們只是用它說明內部類中的機制
內部類的幾種表現形式
一、成員式內部類
定義:成員式內部類如同外部類的一個普通方法
成員式內部類有以下特性:
1.持有父類引用,故可以訪問父類任何訪問許可權的變數、方法
2.非靜態內部類中不能宣告static成員
上邊的程式碼就是成員式內部類
如何訪問成員式內部類:
外部類名.內部類名 變數名 = new 外部類名().new 內部類名();
Person.Xiaoming xiaoming = new Person().new Xiaoming();
二、區域性內部類
1.什麼是區域性內部類
定義:區域性內部類就是定義在程式碼塊、方法體內、作用域({})內的類。
public class Person {
//人在出生的時候選擇性別
private static String[] sex = {"男性","女性"};
public void print() {
class People {
private String name = "xiaoming";
public void print() {
System.out.println("hello world");
}
}
People people = new People();
people.print();
}
}
測試:
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.print();
}
}
區域性內部類有以下特性:
1.不能使用public、private、protected、static等這些修飾符
2.區域性內部類只能在當前方方法中使用,作用域範圍僅限於當前方法中
3.區域性內部類和成員內部類一樣,不能擁有靜態成員,但可以訪問外部成員的所有變數
4.區域性內部類訪問的區域性變數必須使用fianl修飾,在jdk8中自動隱士的加上了final,但是依然是常量,值不能被改變(不知道為什麼)
為什麼不推薦使用區域性內部類?
如果當前方法不是main方法,那麼當前方法呼叫完畢之後,當前方法的棧幀就會被銷燬,方法內部的區域性變數的空間也會被銷燬。
三、匿名內部類
定義:匿名內部類是區域性內部類的一種特殊形式,是一個沒有名稱的內部類。
注意:匿名內部類必須繼承一個父類或者一個介面
1.匿名內部類的由來
首先新建一個抽象類
public abstract class Person {
void sleep() {}
}
繼承這個抽象類並實現它的方法
public class Student extends Person{
private void sleep() {
// TODO Auto-generated method stub
System.out.println("學生在吃");
}
}
最後呼叫
public class Demo3 {
public static void main(String[] args) {
Person person = new Student();
person.sleep();
}
}
可以看到我們在這裡使用了多型的思想,將student類向上轉型到person類當中,這裡我們只是用了一次student類,把我們有沒有什麼辦法跳過這個student類來實現person當中的方法呢?
我們進行相關的改動後:
public class Demo3 {
public static void main(String[] args) {
new Person() {
void sleep() {
System.out.println("學生正在睡覺。。。。");
};
}.sleep();
}
}
可以看到繼承了person類,並在()中實現了響應的抽象方法。
最後這是我們重用的匿名內部類的方式:
public class Person{
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
for(int i=0;i<10;i++) {//3.將要執行的程式碼,寫在run方法中
System.out.println("aaaaaaa");
}
}
}.start();
}
}
最常用的就是利用匿名內部類的方式來開闢一個新的執行緒.
四、靜態內部類
定義:有時候,使用內部類只是為了把一個類隱藏在另一個類的內部,並不需要內部類引用外圍類物件。為此,我們可以將內部類宣告為static,以便取消產生的引用。
特點:
1.在建立外部類例項的時候不必建立外部類例項。
OuterClass.InnerClass in = new OuterClass.InnerClass();
2.靜態內部類可以直接訪問訪問外部類的靜態成員
3.在靜態內部類可以定義靜態和非靜態的成員
4.外部類可以通過完整的類名直接訪問靜態內部類的靜態成員。
public class OuterClass {
String name = "Outer.name";
static String name2 = "Outer.name2";
static class InnerClass{
private void printNmae() {
// TODO Auto-generated method stub
System.out.println(name2);
System.out.println(new OuterClass().name);
}
}
}
有道雲筆記更精彩哦~
文件:第二十三課—java 內部類.note