一、類變量與類方法(靜態變量)
1)類變量
class Child{private String name;//定義一個變量count,是一個類變量(靜態變量)static靜態//該變量最大的特點就是會被Child 類的所有對象訪問public static int count = 0;public Child(String name){this.name = name;}public void join(){System.out.println(name+"加入了游戲");}
}
1.什么是類變量
類變量也叫靜態變量/靜態屬性
,是該類的所有對象共享的變量,任何一個該類的對象去訪問它時,取到的都是相同的值,同樣任何一個該類的
對象去修改它時,修改的也是同一個變量。這個從前面的圖也可看出來。
2.如何定義類變量
定義語法:
訪問修飾符 static 數據類型 變量名;
[推薦]
static 訪問修飾符 數據類型 變量名;
class A{public static string name ="abc";static public int totalNum = 100;
}
3.如何訪問類變量
類名.類變量名
推薦
或者 對象名.類變量名
【靜態變量的訪問修飾符的訪問權限和范圍 和 普通屬性是一樣的。】
4.類變量注意事項和細節
1.什么時候需要用類變量,當我們需要讓某個類的所有對象都共享一個變量時,就可以考慮使用類變量(靜態變量);
比如:定義學生類,統計所有學生共交多少錢。Student(name,staticfee)
2.類變量與實例變量(普通屬性)區別類變量是該類的所有對象共享的,而實例變量是每個對象獨享的
3.加上static稱為類變量或靜態變量,否則稱為實例變量/普通變量/非靜態變量
4.類變量可以通過 類名.類變量名 或者 對象名.類變量名 來訪問,但java設計者 推薦我們使用 類名.類變量名方式訪問。
【前提是 滿足訪問修飾符的訪問權限和范圍】
5.實例變量不能通過 類名.類變量名 方式訪問。
6.即使你沒有創建對象,類變量是在類加載時就初始化了,也就是說,只要類加載了,就可以使用類變量了。【案例演示]
7.類變量的生命周期是隨類的加載開始隨著類消亡而銷毀.
2)類方法基本介紹
1.類方法也叫靜態方法
形式如下:
訪問修飾符 static 數據返回類型 方法名()){ }【推薦】
static 訪問修飾符 數據返回類型 方法名(){ }
類方法的調用使用方式: 類名.類方法名 或者 對象名.類方法名 【前提是 滿足訪問修飾符的訪問權限和范圍】
靜態方法可以訪問靜態屬性/變量
class B{public static void printstart(){System.out.println("打印星星..”);} }
如果我們希望不創建實例/對象,也可以調用某個方法(當工具來用)
這時,把方法做成靜態方法時非常合適
2.類方法使用場景
當方法中不涉及到任何和對象相關的一個成員,則可以將方法設計成靜態方法,提高開發效率
比如:Math類,Arrays類 可以ctrl + b 查看他們的源碼
在實際開發中,往往會將一些通用的方法,設計成靜態方法,無需創建對象就可以使用該方法
例如:冒泡排序,打印一維數組
3)類變量與類方法
1.類方法和普通方法都是隨著類的加載而加載,將結構信息儲存在方法區
類方法中無this的參數
普通方法中隱含著this參數
2.類方法可以通過類名調用,也可以通過對象名調用。
3.普通方法和對象有關,需要通過對象名調用,比如:對象名.方法名(參數),不能通過類名調用。
4.類方法中不允許使用和對象有關的關鍵字,比如super和this。普通方法(成員方法)可以。
5.類方法(靜態方法)中,只能訪問靜態變量 或 靜態方法。
6.普通成員方法,既可以訪問靜態變量(方法),可以訪問普通變量(方法)。
二、main方法理解
1)介紹
2)理解main方法語法
特別提示
-
在 main()方法中,我們可以直接調用 main 方法所在類的靜態方法或靜態屬性。
-
但是,不能直接訪問該類中的非靜態成員,必須創建該類的一個實例對象后,才能通過這個對象去訪問類中的非靜態成員
-
代碼:
public class Main {//靜態的變量/屬性private static String name = "你好";//非靜態的變量/屬性private int n1 = 10000;//靜態方法public static void hi() {System.out.println("Main 的 hi 方法");}//非靜態方法public void cry() {System.out.println("Main 的 cry 方法");}public static void main(String[] args) {
//可以直接使用 name
//1. 靜態方法 main 可以訪問本類的靜態成員System.out.println("name=" + name);hi();//2. 靜態方法 main 不可以訪問本類的非靜態成員//System.out.println("n1 = " + n1);//錯誤//cry();//3. 靜態方法 main 要訪問本類的非靜態成員,需要先創建對象 , 再調用即可Main main = new Main();System.out.println(main.n1);//okmain01.cry();}
}
3)main方法動態傳值
public class CommandPara {public static void main(String[] args) {for (int i = 0; i < args.length; i++) {System.out.println("args[" + i + "]=" + args[i]);}}
}
舊頁面
三、代碼塊
1)基本介紹
代碼化塊又稱為初始化塊,屬于類中的成員[即 是類的一部分],類似于方法,將邏輯語句封裝在方法體中,通過包圍起來。
但和方法不同,沒有方法名,沒有返回,沒有參數,只有方法體,而且不用通過對象或類顯式調用,而是加載類時,或創建對象時隱式調用。
基本語法[修飾符]{代碼
}
注意:
1)修飾符 可選,要寫的話,也只能寫 static。
2)代碼塊分為兩類,使用static 修飾的叫靜態代碼塊,沒有static修飾的,叫普通代碼塊。
3)邏輯語句可以為任何邏輯語句(輸入、輸出、方法調用、循環、判斷等)。
4);號可以寫上,也可以省略。
1.理解:
1)相當于另外一種形式的構造器(對構造器的補充機制),可以做初始化的操作
2)場景: 如果多個構造器中都有重復的語句,可以抽取到初始化塊中,提高代碼的重用性
2.代碼演示:
public class CodeBlock01 {public static void main(String[] args) {Movie movie = new Movie("你好,李煥英");System.out.println("===============");Movie movie2 = new Movie("唐探 3", 100, "陳思誠");}
}class Movie {private String name;private double price;private String director;// 3 個構造器 -> 重載//解讀//(1) 下面的三個構造器都有相同的語句//(2) 這樣代碼看起來比較冗余//(3) 這時我們可以把相同的語句,放入到一個代碼塊中,即可//(4) 這樣當我們不管調用哪個構造器,創建對象,都會先調用代碼塊的內容//(5) 代碼塊調用的順序優先于構造器{System.out.println("電影屏幕打開...");System.out.println("廣告開始...");System.out.println("電影正是開始...");};public Movie(String name) {System.out.println("Movie(String name) 被調用...");this.name = name;}public Movie(String name, double price) {this.name = name;this.price = price;}public Movie(String name, double price, String director) {System.out.println("Movie(String name, double price, String director) 被調用...");this.name = name;this.price = price;this.director = director;}
}
2)代碼塊使用細節和討論
1.細節一
public class CodeBlockDetail01 {public static void main(String[] args) {//類被加載的情況舉例// 1. 創建對象實例時(new)// AA aa = new AA();// 2. 創建子類對象實例,父類也會被加載, 而且,父類先被加載,子類后被加載// AA aa2 = new AA();// 3. 使用類的靜態成員時(靜態屬性,靜態方法)// System.out.println(Cat.n1);// static 代碼塊,是在類加載時,執行的,而且只會執行一次. // DD dd = new DD();// DD dd1 = new DD();// 普通的代碼塊,在創建對象實例時,會被隱式的調用。// 被創建一次,就會調用一次// 如果只是使用類的靜態成員時,普通代碼塊并不會執行System.out.println(DD.n1);//8888, 靜態模塊塊一定會執行}
}
class DD {public static int n1 = 8888;//靜態屬性//靜態代碼塊static {System.out.println("DD 的靜態代碼 1 被執行...");//}
//普通代碼塊, 在 new 對象時,被調用,而且是每創建一個對象,就調用一次//可以這樣簡單的,理解 普通代碼塊是構造器的補充{System.out.println("DD 的普通代碼塊...");}
}
class Animal {//靜態代碼塊static {System.out.println("Animal 的靜態代碼 1 被執行...");//}
}
class Cat extends Animal {public static int n1 = 999;//靜態屬性//靜態代碼塊static {System.out.println("Cat 的靜態代碼 1 被執行...");//}
}
class BB {//靜態代碼塊static {System.out.println("BB 的靜態代碼 1 被執行...");//1}
}
class AA extends BB {//靜態代碼塊static {System.out.println("AA 的靜態代碼 1 被執行...");//2}
}
2.細節二
public class CodeBlockDetail02 {public static void main(String[] args) {A a = new A();//執行順序// (1) A 靜態代碼塊 01 // (2) getN1 被調用...// (3) A 普通代碼塊 01// (4) getN2 被調用...// (5) A() 構造器被調用}
}
class A {{ //普通代碼塊System.out.println("A 普通代碼塊 01");} private int n2 = getN2();//普通屬性的初始化static { //靜態代碼塊System.out.println("A 靜態代碼塊 01");}//靜態屬性的初始化private static int n1 = getN1();public static int getN1() {System.out.println("getN1 被調用...");return 100;}public int getN2() { //普通方法/非靜態方法System.out.println("getN2 被調用...");return 200;}//無參構造器public A() {System.out.println("A() 構造器被調用");}
}
3.細節三
構造器 的最前面其實隱含了 super() 和 調用普通代碼塊,靜態相關的代碼塊,屬性初始化,在類加載時,就執行完畢。
因此是優先于 構造器和普通代碼塊執行。
class A {public A(){//構造器//這里有隱藏的執行要求//隱藏的 super();//調用普通代碼塊System.out.println("ok"");}
}
public class CodeBlockDetail03 {public static void main(String[] args) {new BBB();//(1)AAA 的普通代碼塊//(2)AAA() 構造器被調用//(3)BBB 的普通代碼塊//(4)BBB() 構造器被調用}
}class AAA { //父類 Object{System.out.println("AAA 的普通代碼塊");}public AAA() {//(1)super()//(2)調用本類的普通代碼塊System.out.println("AAA() 構造器被調用....");}}class BBB extends AAA {{System.out.println("BBB 的普通代碼塊...");}public BBB() {//(1)super()//(2)調用本類的普通代碼塊System.out.println("BBB() 構造器被調用....");}
}
4.細節四
1)我們看一下創建一個子類時(繼承關系),他們的靜態代碼塊,靜態屬性初始化,普通代碼塊,普通屬性初始化,構造方法的調用順序如下:
- 父類的靜態代碼塊和靜態屬性(優先級一樣,按定義順序執行)
- 子類的靜態代碼塊和靜態屬性(優先級一樣,按定義順序執行)
- 父類的普通代碼塊和普通屬性初始化(優先級一樣,按定義順序執行)
- 父類的構造方法
- 子類的普通代碼塊和普通屬性初始化(優先級一樣,按定義順序執行)
- 子類的構造方法 // 面試題
- 靜態方法與普通方法只有在調用時才執行,與順序無關
2)靜態代碼塊只能直接調用靜態成員(靜態屬性和靜態方法),普通代碼塊可以調用任意成員。
public class CodeBlockDetail04 {public static void main(String[] args) {//說明//(1) 進行類的加載//1.1 先加載 父類 A02 1.2 再加載 B02//(2) 創建對象//2.1 從子類的構造器開始new B02();//對象new C02();}
}class A02 { //父類private static int n1 = getVal01();static {System.out.println("A02 的一個靜態代碼塊..");//(2)}{System.out.println("A02 的第一個普通代碼塊..");//(5)}public int n3 = getVal02();//普通屬性的初始化public static int getVal01() {System.out.println("getVal01");//(1)return 10;}public int getVal02() {System.out.println("getVal02");//(6)return 10;}public A02() {//構造器//隱藏//super()//普通代碼和普通屬性的初始化...... System.out.println("A02 的構造器");//(7)}
}class C02 {private int n1 = 100;private static int n2 = 200;private void m1() {}private static void m2() {}static {//靜態代碼塊,只能調用靜態成員//System.out.println(n1);錯誤System.out.println(n2);//ok//m1();//錯誤m2();}{//普通代碼塊,可以使用任意成員System.out.println(n1);System.out.println(n2);//okm1();m2();}
}class B02 extends A02 { //private static int n3 = getVal03();static {System.out.println("B02 的一個靜態代碼塊..");//(4)}public int n5 = getVal04();{System.out.println("B02 的第一個普通代碼塊..");//(9)}System.out.println("getVal03");//(3)return 10;
}public int getVal04() {System.out.println("getVal04");//(8)return 10;}// public B02() {//構造器//隱藏了//super()//普通代碼塊和普通屬性的初始化... System.out.println("B02 的構造器");//(10)// TODO Auto-generated constructor stub
}
四、單例設計模式
1)介紹
1.靜態方法和屬性的經典使用
2.設計模式是在大量的實踐中總結和理論化之后優選的代碼結構、編程風格以及解決問題的思考方式。
設計模式就像是經典的棋譜,不同的棋局,我們用不同的棋譜,免去我們自己再思考和摸索
2)什么是單例模式
所謂類的單例設計模式,就是采取一定的方法保證在整個的軟件系統中,對某個類只能存在一個對象實例,
并且該類只提供一個取得其對象實例的方法
單例模式有兩種方式:
1)餓漢式
2)懶漢式
3)單例模式
步驟如下:
1)構造器私有化 -> 防止直接 new
2)類的內部創建對象
3)向外暴露一個靜態的公共方法。getInstance
1.餓漢式
public class SingleTon01 {public static void main(String[] args) {// GirlFriend xh = new GirlFriend("小紅");// GirlFriend xb = new GirlFriend("小白");//通過方法可以獲取對象GirlFriend instance = GirlFriend.getInstance();System.out.println(instance);GirlFriend instance2 = GirlFriend.getInstance();System.out.println(instance2);//兩個對象是一樣的System.out.println(instance == instance2);//T}
}//有一個類, GirlFriend//只能有一個女朋友class GirlFriend {private String name;//為了能夠在靜態方法中,返回 gf 對象,需要將其修飾為 static//對象,通常是重量級對象, 餓漢式可能造成創建了對象,但是沒有使用. private static GirlFriend gf = new GirlFriend("小紅紅");//如何保障我們只能創建一個 GirlFriend 對象//步驟[單例模式-餓漢式]//1. 將構造器私有化//2. 在類的內部直接創建對象(該對象是 static)//3. 提供一個公共的 static 方法,返回 gf 對象private GirlFriend(String name) {System.out.println("構造器被調用.");this.name = name;}public static GirlFriend getInstance() {return gf;}@Overridepublic String toString() {return "GirlFriend{" +"name='" + name + '\'' +'}';}}
2.懶漢式
public class SingleTon02 {public static void main(String[] args) {//new Cat("大黃");//System.out.println(Cat.n1);Cat instance = Cat.getInstance();System.out.println(instance);//再次調用 getInstanceCat instance2 = Cat.getInstance();System.out.println(instance2);System.out.println(instance == instance2);//T}}
//希望在程序運行過程中,只能創建一個 Cat 對象//使用單例模式class Cat {private String name;//public static int n1 = 999;private static Cat cat; //默認是 null//步驟//1.仍然構造器私有化//2.定義一個 static 靜態屬性對象//3.提供一個 public 的 static 方法,可以返回一個 Cat 對象//4.懶漢式,只有當用戶使用 getInstance 時,才返回 cat 對象, 后面再次調用時,會返回上次創建的 cat 對象// 從而保證了單例private Cat(String name) {System.out.println("構造器調用...");this.name = name;}public static Cat getInstance() {if (cat == null) {//如果還沒有創建 cat 對象cat = new Cat("小可愛");}return cat;}@Overridepublic String toString() {return "Cat{" +"name='" + name + '\'' +'}';}}
4)懶漢與餓漢區別
餓漢:想要好多好多,不需要用的也想要;
懶漢:用不著就不要了,要用的時候再創建;
二者最主要的區別在于創建對象的時機不同:
- 餓漢式是在類加載就創建了對象實例,而懶漢式是在使用時才創建。
- 餓漢式不存在線程安全問題,懶漢式存在線程安全問題。
- 餓漢式存在浪費資源的可能。因為如果程序員一個對象實例都沒有使用,那么餓漢式創建的對象就浪費了,懶漢式是使用時才創建,就不存在這個問題。
- 在我們javaSE標準類中,java.lang.Runtime就是經典的單例模式。
五、Final基本使用
1)介紹
final 中文意思:
最后的,最終的.
final 可以修飾類、屬性、方法和局部變量,
在某些情況下,程序員可能有以下需求,就會使用到final:
1)當不希望類被繼承時,可以用final修飾。【案例演示】
//如果我們要求A類不能被其他類繼承
//可以使用final修飾 A類final class A {}
class B extends A {}//錯誤
2)當不希望父類的某個方法被子類覆蓋/重寫(override)時,可以用final關鍵字修飾。【案例演示: 訪問修飾符 final 返回類型 方法名】
3)當不希望類的的某個屬性的值被修改,可以用final修飾。【案例演示: public final double TAX RATE=0.08】
4)當不希望某個局部變量被修改,可以使用final修飾。【案例演示: final doubleTAX RATE=0.08】
注意:
1.final必須在定義時初始化
2.final可修飾類、屬性、方法
在Java中,final
關鍵字可以用于以下場景:
- 修飾類,表示該類不能被繼承。
- 修飾方法,表示該方法不能被子類重寫。
- 修飾變量(無論是實例變量、類變量或局部變量),表示該變量的值一旦賦值后就不能再改變。
2)重點
1)final修飾的屬性又叫常量,一般 用 XX_XX_XX 來命名
2)final修飾的屬性在定義時,必須賦初值,并且以后不能再修改,賦值可以在如下位置之一【選擇一個位置賦初值即可】:
- 定義時:如 public final double TAX RATE=0.08:
- 在構造器中
- 在代碼塊中
3)如果final修飾的屬性是靜態的,則初始化的位置只能是
- 定義時
- 在靜態代碼塊,不能在構造器中賦值。
4)final類不能繼承,但是可以實例化對象。[A2類]
5)如果類不是final類,但是含有final方法,則該方法雖然不能重寫,但是可以被繼承。[A3類]
6)一般來說,如果一個類已經是final類了,就沒有必要再將方法修飾成final方法
7)final不能修飾構造方法(即構造器)
8)final 和 static 往往搭配使用,效率更高,底層編譯器做了優化處理。
class Demo{public static final int i=16; static{System.out.println("你好~");}
}
9)包裝類(Integer,Double,Float,Boolean等都是final),String也是final類。
六、抽象類與接口
1)抽象類
父類方法的不確定性
當父類的某些方法,需要聲明,但是又不確定如何實現時,可以將其聲明為抽象方法,那么這個類就是抽象類
但有一個類中存在抽象方法時,需要將該類聲明為abstract類
abstract class Animal{String name;int age;abstract public void cry();
}
抽象類的價值更多作用在于設計,是設計者設計好后,讓子類繼承并實現抽象類()
- 抽象類不能被實例化
- 抽象類不一定包含了abstract方法,抽象類可以沒有abstract方法
- 一旦包含了abstract方法,則這個類必須聲明為abstract
- abstract只能修飾類和方法,不能修飾屬性和其他的
- 抽象類可以有任意成員、靜態屬性等等
- 抽象方法不能有主體,即不能實現.如圖所示
abstract void aaa(){};//{}錯誤
-
如果一個類繼承了抽象類,則它必須實現抽象類的所有抽象方法,除非它自己也聲明為abstract類
-
抽象方法不能使用private, final,和static來修飾,因為這些關鍵字都是和重寫相違背的
實際上,abstract
可以修飾類和方法,但不能修飾屬性。abstract
修飾的類稱為抽象類,不能被實例化;
修飾的方法稱為抽象方法,沒有具體實現(沒有方法體)。
2)接口 interface
1.基本介紹:
接口就是給出一些沒有實現的方法,封裝到一起,到某個類要使用的時候,再根據具體情況把這些類寫出來。
//定義接口
interface 接口名{//屬性//方法
}//實現接口
class 類名 implements 接口{自己屬性;自己方法;必須實現的接口抽象方法;
}
主函數
public class Main {public static void main(String[] args) {}
}//如果一個類 implements 實現接口
//需要將該接口中所有的抽象方法都實現
//快捷鍵實現該方法 鼠標放在紅色波浪線處,按下alt+enter鍵
class A implements Ainterface{@Overridepublic void h1() {System.out.println("h1");}
}
public interface Ainterface {public int n1 = 10;//在抽象方法中可以省略abstract關鍵字public void h1();//在jdk8之后,可以有默認實現方法,需要使用default關鍵字修飾default public void h2(){System.out.println("h2");}//在jdk8之后,可以有靜態方法public static void cry(){System.out.println("cry");}
}
2.使用細節
1.接口不能被實例化,向上轉型
2.接口中所有的方法是public方法,接口中抽象方法,可以不用abstract修飾
3.一個普通類實現接口,就必須將該接口的所有方法都實現
4.抽象類去實現接口,可以不用實現接口的方法
5.一個類可以實現多個接口
6.接口中的屬性,只能是final的,而且是 public static final 修飾符。 比如int a=1;
實際上是 public static final int a=1;(必須初始化)
7.接口中屬性的訪問形式: 接口名.屬性名
8.一個接口不能繼承其它的類,但是可以繼承多個別的接口[舉例]
interface A extends B,C{}
9.接口的修飾符 只能是 public 和默認,這點和類的修飾符是一樣的。
10.接口名必須與文件名相同
3)接口和繼承區別
當子類繼承了父類,就自動的擁有父類的功能
如果子類需要擴展功能,可以通過實現接口的方式擴展.
可以理解 實現接口 是 對 java 單繼承機制的一種補充
4)接口的多態特性
七、內部類
1)基本介紹
一個類的內部又完整的嵌套了另一個類結構。被嵌套的類稱為內部類(inner class),嵌套其他類的類稱為外部類(outer class)。是我們類的第五大成員【思考:類的五大成員是哪些?[屬性、方法、構造器、代碼塊、內部類]】,內部類最大的特點就是可以直接訪問私有屬性,并且可以體現類與類之間的包含關系,注意:內部類是學習的難點,同時也是重點,后面看底層源碼時,有大量的內部類。
2)基本語法
class Outer{ //外部類class Inner{//內部類}
}
class Other{//外部其他類
}
3)內部類分類
定義在外部類局部位置上(比如方法內):
- 局部內部類(有類名)
- 匿名內部類(沒有類名,重點!!!)
定義在外部類的成員位置上:
- 成員內部類(沒用static修飾)
- 靜態內部類(使用static修飾)
4)局部類的使用
說明:局部內部類是定義在外部類的局部位置,比如方法中,并且有類名
- 可以直接訪問外部類的所有成員,包含私有的
- 不能添加訪問修飾符,因為它的地位就是一個局部變量。局部變量是不能使用修飾符的。但是可以使用final 修飾,因為局部變量也可以使用final。
- 作用域:僅僅在定義它的方法或代碼塊中。
- 局部內部類—訪問---->外部類的成員 [訪問方式:直接訪問]
- 外部類—訪問---->局部內部類的成員訪問方式:創建對象,再訪問(注意:必須在作用域內)
記住:
(1) 局部內部類定義在方法中/代碼塊
(2) 作用域在方法體或者代碼塊中
(3) 本質仍然是一個類
-
外部其他類—不能訪問----->局部內部類(因為 局部內部類地位是一個局部變量)
-
如果外部類和局部內部類的成員重名時,默認遵循就近原則,如果想訪問外部類的成員,則可以使用(外部類名.this.成員)去訪問
System.out.println("外部類的n2="+ 外部類名.this.n2);
/** * 演示局部內部類的使用 */
public class LocalInnerClass {public static void main(String[] args) { //演示一遍 Outer02 outer02 = new Outer02(); outer02.m1(); System.out.println("outer02 的 hashcode=" + outer02); }
}
class Outer02 {//外部類 private int n1 = 100; private void m2() { System.out.println("Outer02 m2()"); }//私有方法 public void m1() {//方法 //1.局部內部類是定義在外部類的局部位置,通常在方法 //3.不能添加訪問修飾符,但是可以使用 final 修飾 //4.作用域 : 僅僅在定義它的方法或代碼塊中 final class Inner02 {//局部內部類(本質仍然是一個類) //2.可以直接訪問外部類的所有成員,包含私有的 private int n1 = 800; public void f1() { //5. 局部內部類可以直接訪問外部類的成員,比如下面 外部類 n1 和 m2()//7. 如果外部類和局部內部類的成員重名時,默認遵循就近原則,如果想訪問外部類的成員,
// 使用 外部類名.this.成員 去訪問
// Outer02.this 本質就是外部類的對象, 即哪個對象調用了 m1, Outer02.this 就是哪個對象 System.out.println("n1=" + n1 + " 外部類的 n1=" + Outer02.this.n1); System.out.println("Outer02.this hashcode=" + Outer02.this); m2(); } }
//6. 外部類在方法中,可以創建 Inner02 對象,然后調用方法即可 Inner02 inner02 = new Inner02(); inner02.f1(); }
}
5)匿名內部類的使用(重要)
(1)本質是類
(2)內部類
(3)該類沒有名字
(4)同時還是一個對象說明:匿名內部類是定義在外部類的局部位置,比如方法中,并且沒有類名
- 匿名內部類的基本語法
new 類或接口(參數列表){類體
}
- 匿名內部類的語法比較奇特,請大家注意,因為匿名內部類既是一個類的定義同時它本身也是一個對象,因此從語法上看,它既有定義類的特征,也有創建對象的特征,對前面代碼分析可以看出這個特點,因此可以調用匿名內部類方法
- 可以直接訪問外部類的所有成員,包含私有的。
- 不能添加訪問修飾符,因為它的地位就是一個局部變量。[過]
- 作用域:僅僅在定義它的方法或代碼塊中。[過]
- 匿名內部類—訪問---->外部類成員。[訪問方式:直接訪問]
- 外部其他類—不能訪問----->匿名內部類(因為 匿名內部類地位是一個局部變量)。
- 如果外部類和匿名內部類的成員重名時,匿名內部類訪問的話,默認遵循就近原則如果想訪問。外部類的成員,則可以使用(外部類名.this.成員)去訪問。