內部類別和匿名內部類別的用法
一、內部類別:
(1)內部類別的同名方法
內部類別可以呼叫外層類別的方法,如果內部類別有同名方法必須使用"OuterClass.this.MethodName()"格式呼叫(其中OuterClass與MethodName換成實際外部類別名稱及其方法;this為關鍵字,表示外部類別的參考);若內部類別無同名方法可以直接呼叫外圍類別的方法。
但外圍類別無法直接呼叫內部類別的private方法,外部類別同樣無法直接呼叫其它類別的private方法。注意:內部類別直接使用外部類別的方法與該方法的權限與是否static無關,它取決於內部類別是否有同名方法。
package innerclass; public class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { OuterClass t = new OuterClass(); OuterClass.Innerclass in = t.new Innerclass(); in.innerMethod(); } class Innerclass { public void innerMethod() { OuterClass.this.outerMethod();// 内部类成员方法与外部类成员方法同名时,使用this调用外部类的方法 outerMethod();// 内部类没有同名方法时执行外部类的方法 } private void outerMethod() { System.out.println("It's Method of Innerclass"); } } }
輸出結果為:
It's Method of OuterClass It's Method of Innerclass
(2)內部類別的實例化
內部類別實例化不同於普通類,普通類別可以在任意需要的時候實例化,而內部類別必須在外層類別實例化以後方可實例化,並與外部類別建立關係
因此在外部類別中的非static方法中,是可以實例化內部類別物件
private void outerMethod() { System.out.println("It's Method of OuterClass"); Innerclass in = new Innerclass();//在外部类的outerMethod方法中实例化内部类是可以啊 }
但在static方法中,就要注意! ! ! !不能在static方法中直接new內部類,否則出現錯誤:
No enclosing instance of type OuterClass is accessible. Must qualify the allocation with an enclosing instance of type OuterClass (e.g. x. A(insta) wh: new instance. OuterClass).
這是因為靜態方法是在類別實例化之前就可以使用的,透過類別名稱調用,這時動態內部類別都還沒實例化呢,怎麼用,總不能調用一個不存在的東西吧。
如果想在Static方法中new內部類,可以把內部類別宣告為Static
public class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { Innerclass in = new Innerclass(); in.innerMethod(); } static class Innerclass {//把内部类声明为static public void innerMethod() { System.out.println("It's Method of innerMethod"); } } }
當然,一般不使用static的方式,而是推薦這種方法:x.new A() ,其中x是外部類OuterClass的實例,A是內部類別Innerclass
package innerclass; public class OuterClass { private void outerMethod() { System.out.println("It's Method of OuterClass"); } public static void main(String[] args) { OuterClass.Innerclass in = new OuterClass().new Innerclass();//使用x.new A()的方式 in.innerMethod(); } class Innerclass { public void innerMethod() { System.out.println("It's Method of innerMethod"); } } }
x.new A() ,其中x是外部類別OuterClass的實例,A是類別部類別Innerclass,當然可以分割如下,這樣就顯然很明白:
public static void main(String[] args) { OuterClass out = new OuterClass();//外部实例 OuterClass.Innerclass in = out.new Innerclass();//外部实例.new 外部类 in.innerMethod(); }
(3)什麼情況下使用內部類別
典型的情況是,內部類別繼承自某個類別或實作某個接口,內部類別的程式碼操作建立其的外層類別的物件。所以你可以認為內部類別提供了某種進
入其外層類別的視窗。
使用內部類別最吸引人的原因是:每個內部類別都能獨立地繼承自一個(介面的)實現,所以無論外層類別是否已經繼承了某個(介面的)實
現,對於內部類別都沒有影響。如果沒有內部類別提供的可以繼承多個具體的或抽象的類別的能力,一些設計與程式設計問題就很難解決。從這個角
度看,內部類別使得多重繼承的解決方案變得完整。介面解決了部分問題,而內部類別有效地實現了「多重繼承」。
(4)在靜態方法中實例化內部類別範例:(內部類別放在靜態方法中)
package javatest2; public class JavaTest2 { public static void main(String[] args) { class Boy implements Person { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } } Person per = new Boy(); per.speak();// 可调用 per.say();// 不能调用 } } interface Person { public void speak(); }
per.speak()可調用,而per.say()不能調用,這時因為per是Person對象,要呼叫子類別的方法,可以強制向下轉型為:((Boy) per).say();或直接改為Boy per = new Boy();。從中可發現,若要呼叫內部類別的自訂的方法,必須透過內部類別的物件來呼叫。那麼,匿名內部類別連名字都沒有,怎麼呼叫內部類別自訂的方法呢?
(二)匿名內部類別
匿名內部類別也就是沒有名字的內部類別正因為沒有名字,所以匿名內部類別只能使用一次,它通常用來簡化程式碼編寫,但使用匿名內部類別還有個前提條件:必須繼承一個父類或實作一個接口,但最多只能繼承一個父類,或實作一個接口。
關於匿名內部類別還有以下兩條規則:
1)匿名內部類別不能是抽象類別,因為系統在建立匿名內部類別的時候,會立即建立內部類別的物件。因此不允許將匿名內部類別定義成抽象類別。
2)匿名內部類別不等定義建構器(建構方法),因為匿名內部類別沒有類別名,所以無法定義建構器,但匿名內部類別可以定義實例初始化區塊,
怎麼判斷一個匿名類別的存在啊?看不見名字,感覺只是父類別new出一個物件而已,沒有匿名類別的名字。
先看段偽代碼
abstract class Father(){ .... } public class Test{ Father f1 = new Father(){ .... } //这里就是有个匿名内部类 }
一般來說,new 一個物件時小括號後應該是分號,也就是new出物件該語句就結束了。但出現匿名內部類別就不一樣,小括號後面接的是大括號,大括號中是該new 出物件的具體的實作方法。因為我們知道,一個抽象類別是不能直接new 的,必須先有實作類別了我們才能new出它的實作類別。上面的偽代碼就是表示new 的是Father的實作類,這個實作類別是個匿名內部類別。
其實拆分上面的匿名內部類別可為:
class SonOne extends Father{ ... //这里的代码和上面匿名内部类,大括号中的代码是一样的 } public class Test{ Father f1 = new SonOne() ; }
先看一個例子,體會一下匿名內部類別的用法:
运行结果:eat something
可以看到,我们直接将抽象类Person中的方法在大括号中实现了,这样便可以省略一个类的书写。并且,匿名内部类还能用于接口上
public class JavaTest2 { public static void main(String[] args) { Person per = new Person() { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } }; per.speak();// 可调用 per.say();// 出错,不能调用 } } interface Person { public void speak(); }
这里per.speak()是可以正常调用的,但per.say()不能调用,为什么呢?注意Person per = new Person()创建的是Person的对象,而非匿名内部类的对象。其实匿名内部类连名字都没有,你咋实例对象去调用它的方法呢?但继承父类的方法和实现的方法是可以正常调用的,本例子中,匿名内部类实现了接口Person的speak方法,因此可以借助Person的对象去调用。
若你确实想调用匿名内部类的自定义的方法say(),当然也有方法:
(1)类似于speak方法的使用,先在Person接口中声明say()方法,再在匿名内部类中覆写此方法。
(2)其实匿名内部类中隐含一个匿名对象,通过该方法可以直接调用say()和speak()方法;代码修改如下:
public class JavaTest2 { public static void main(String[] args) { new Person() { public void say() {// 匿名内部类自定义的方法say System.out.println("say方法调用"); } @Override public void speak() {// 实现接口的的方法speak System.out.println("speak方法调用"); } }.say();// 直接调用匿名内部类的方法 } } interface Person { public void speak(); }
更多内部类和匿名内部类的用法相关文章请关注PHP中文网!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

匿名內部類別可導致記憶體洩漏,問題在於它們持有外部類別的引用,從而阻止外部類別被垃圾回收。解決方法包括:1.使用弱引用,當外部類別不再被強引用持有時,垃圾回收器會立即回收弱引用物件;2.使用軟引用,垃圾回收器會在進行垃圾回收時需要記憶體時才回收軟引用物件。在實戰中,例如Android應用程式中,可以透過使用弱引用來解決因匿名內部類別引起的記憶體洩漏問題,從而在不需要監聽器時回收匿名內部類別。

匿名內部類別是Java中沒有明確名稱、透過new表達式創建的特殊內部類,主要用於實作特定介面或擴展抽象類,並在創建後立即使用。常見的匿名內部類別設計模式包括:適配器模式:將一個介面轉換為另一個介面。策略模式:定義和替換演算法。觀察者模式:註冊觀察者並處理事件。它在實際應用中非常有用,例如按字串長度排序TreeSet、建立匿名執行緒等。

匿名內部類別在Java中作為方便建立子類別、簡化程式碼和處理事件(例如按鈕點擊)的特殊內部類別。實戰案例包括:事件處理:使用匿名內部類別為按鈕新增點選事件監聽器。資料轉換:使用Collections.sort方法和匿名內部類別作為比較器對集合進行排序。

匿名內部類別的效能問題在於每次使用都會重新創建,可透過以下策略最佳化:1.將匿名內部類別儲存在局部變數中;2.使用非靜態內部類別;3.使用lambda表達式。實戰測試顯示lambda表達式最佳化效果最佳。

匿名內部類別的生命週期由其作用域決定:方法局部內部類別:僅在創建它的方法範圍內有效。建構器內部類別:與外部類別實例綁定,當外部類別實例釋放時釋放。靜態內部類別:與外部類別同時載入卸載。

匿名內部類別可簡化多執行緒程式碼的創建,無需命名,支援即時定義和使用執行緒類別。主要優勢在於簡化程式碼,而限制是無法擴展。在需要快速建立一兩個執行緒時使用,保持程式碼簡短,如果需要更複雜的邏輯,應建立單獨的類別檔案。
