Java 匿名對象與匿名內部類的使用
很多小伙伴對匿名對象和匿名內部類的寫法有點陌生,這里專門寫一篇來幫助大家認識一下他們的寫法。
一、匿名對象
比如現在有一個Student
類,里面啥也沒有寫:
/** * ClassName: Student * Package: PACKAGE_NAME * Description: * * @Author 雨翼輕塵 * @Create 2024/1/31 0031 11:39 */ public class Student { }
然后還有一個測試類Test
:
/** * ClassName: Test * Package: PACKAGE_NAME * Description: * * @Author 雨翼輕塵 * @Create 2024/1/31 0031 11:39 */ public class Test { public static void main(String[] args) { //類->對象 格式:類名Student 對象名stu = new 類名Student(); Student stu=new Student(); } }
類->對象
格式:類名Student 對象名stu = new 類名Student();
如下:
public class Test { public static void main(String[] args) { //類->對象 格式:類名Student 對象名stu = new 類名Student(); Student stu=new Student(); } }
現在打印出來就是地址值:
如果這樣,也是地址值:
每new
一次,就會創(chuàng)建一個對象,相當于在堆中開辟了一塊空間,所以地址值都不一樣,如下:
public class Test { public static void main(String[] args) { //類->對象 格式:類名Student 對象名stu = new 類名Student(); Student stu=new Student(); System.out.println(stu); //test.Student@4eec7777 System.out.println(new Student()); //test.Student@3b07d329 System.out.println(new Student()); //test.Student@41629346 } }
上面的stu
是有名字的對象,而現在的new Student()
沒有對象名,叫做匿名對象。
有了new關鍵字,就表示在堆里面創(chuàng)建了一個新的空間。
現在在Student
類里面加上屬性,比如:
public class Student { String name; //姓名 }
正常情況下,name
可以賦值:
public class Test { public static void main(String[] args) { //類->對象 格式:類名Student 對象名stu = new 類名Student(); Student stu=new Student(); System.out.println(stu); //test.Student@4eec7777 stu.name="張三"; System.out.println(stu.name); //張三 } }
打印出來就是“張三”:
??那么new Student()
可以給name
賦值嗎?
是可以的。
它是一個匿名對象,雖然沒有名字,但是它可以給屬性賦值的。如下:
public class Test { public static void main(String[] args) { System.out.println(new Student().name="李四"); //test.Student@3b07d329 System.out.println(new Student()); //test.Student@41629346 } }
輸出:
“匿名對象”只不過是一個沒有名字的對象而已,依然是一個對象。
若是方法依然可以調用的,比如現在寫一個方法eat
,如下:
public class Student { String name; //姓名 public void eat(){ System.out.println("使勁吃..."); } }
測試類里面:
public class Test { public static void main(String[] args) { //類->對象 格式:類名Student 對象名stu = new 類名Student(); Student stu=new Student(); System.out.println(stu); //test.Student@4eec7777 stu.name="張三"; System.out.println(stu.name); //張三 stu.eat(); System.out.println(new Student().name="李四"); //test.Student@3b07d329 System.out.println(new Student()); //test.Student@41629346 new Student().eat(); } }
輸出結果:
像這樣直接new了一個類名,但是沒有給對象名的,叫做“匿名對象”。
區(qū)別就是,有名的對象它可以多次使用,而匿名對象卻只能使用一次。
二、匿名內部類
提供一個接口IA
,里面寫一個抽象方法play
,如下:
package test; /** * ClassName: IA * Package: test * Description: * * @Author 雨翼輕塵 * @Create 2024/1/31 0031 12:08 */ public interface IA { //抽象方法 void play(); }
抽象方法省略了public abstract
。
抽象方法要想重寫,需要有子類去實現這個接口。
接下來寫一個實現類IAImpl
,將接口里面的抽象方法重寫一下,如下:
package test; /** * ClassName: IAImpl * Package: test * Description: * * @Author 雨翼輕塵 * @Create 2024/1/31 0031 12:12 */ public class IAImpl implements IA{ @Override public void play() { System.out.println("打游戲..."); } }
然后再來一個測試類IATest
,以多態(tài)的方式創(chuàng)建接口:
package test; /** * ClassName: IATest * Package: test * Description: * * @Author 雨翼輕塵 * @Create 2024/1/31 0031 12:14 */ public class IATest { public static void main(String[] args) { IA ia=new IAImpl(); //多態(tài) } }
IA ia=new IAImpl();
,接口不能傳對象,口訣:多態(tài)–“父父new子”。
實現類可以看成繼承關系。
現在來使用ia調用play
方法:
public class IATest { public static void main(String[] args) { IA ia=new IAImpl(); //多態(tài) ia.play(); //編譯看左,運行看右 } }
輸出:
ia.play();
“編譯看左,運行看右”,接口IA
里面有play
方法,它被實現類IAImpl
重寫了,所以執(zhí)行的時候是看實現類里面的。
現在我們來看一下這個藍色部分,這個括號里面只有一個方法的重寫:
之前說接口不能new,我們來看一下這樣:
??看一下剛才的兩個藍色部分,有什么區(qū)別?
沒有區(qū)別!只不過右邊多了一個最后的分號。
既然花括號里面的內容和實現類的一模一樣,那我們可以使用i調用里面的方法play
,如下:
public class IATest { public static void main(String[] args) { IA ia=new IAImpl(); //多態(tài) ia.play(); //編譯看左,運行看右 System.out.println("------------------"); IA i=new IA() { @Override public void play() { System.out.println("打游戲哈哈哈..."); } }; i.play(); } }
打印輸出:
可以看到,調用的是花括號里面重寫IA接口的方法。
我們new了一個接口之后,后面的大括號里面可以看作一個類的結構。如下:
在花括號里面是對方法的重寫,重寫的是IA接口的抽象方法。
現在寫一個IB接口
:
public interface IB { //抽象方法 void sleep(); }
再寫一個測試類IBTest
:
public class IBTest { public static void main(String[] args) { } }
目前IB接口沒有實現類,還可以創(chuàng)建對象嗎?
可以的,如下:
public class IBTest { public static void main(String[] args) { IB ib=new IB() { @Override public void sleep() { } }; } }
這個結構和它的實現類結構是一樣的(藍色部分):
現在就不需要接口的實現類了,上面藍色部分就是它的匿名實現類
。
通過ib.sleep()
來調用重寫的抽象方法:
public class IBTest { public static void main(String[] args) { IB ib=new IB() { @Override public void sleep() { System.out.println("睡覺..."); } }; ib.sleep(); } }
輸出:
這就是匿名內部類,new的接口,相當于是把實現類的結構拿了過來,重寫了一下。
??還有一種寫法。
剛才說了匿名對象,可以直接拿匿名對象去調用方法。
同樣,我們還可以使用匿名內部類直接調用方法。
這個叫做創(chuàng)建“匿名實現類的有名對象”,如下結構:
IB ib = new IB(){ //sleep()方法的重寫 }; ib.sleep(); //用ib調用方法sleep()
現在我們直接new一個接口IB
:
new IB(){ //sleep()方法的重寫 }
然后直接用它調用sleep()
方法,如下:
new IB(){ //sleep()方法的重寫 }.sleep();
??代碼
public class IBTest { public static void main(String[] args) { IB ib=new IB() { @Override public void sleep() { System.out.println("睡覺..."); } }; ib.sleep(); System.out.println("-------"); new IB(){ @Override public void sleep() { System.out.println("晚安嘍"); } }.sleep(); } }
??輸出
這里的ib
就表示:
那就可以直接拿它調用sleep()
方法:
??看一下正常的一般寫法:
再看一下這兩種方式:
到此這篇關于Java 匿名對象與匿名內部類的使用的文章就介紹到這了,更多相關Java 匿名對象與匿名內部類內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Eclipse可視化插件WindowBuilder的安裝方法
這篇文章主要介紹了Eclipse可視化插件WindowBuilder的安裝方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06