1、
為什么父類的引用能指向子類對(duì)象呢?
父類定義了子類中一定存在的方法和屬性。
同理,接口的引用指向他的實(shí)例化對(duì)象也是因?yàn)閷?shí)例化對(duì)象中必然要實(shí)現(xiàn) 接口中定義的方法和屬性。
對(duì)象的類型還是new出來的類型(或方法返回的類型,如DriverManager.getConnection(String a,String b,String c)靜態(tài)方法返回Connection接口的實(shí)例化對(duì)象)。
也可以這樣寫:
Connection conn =new XXX () XXX為實(shí)現(xiàn)Connection接口的類。
只不過引用(變量名)如conn只能調(diào)用接口定義的方法。
這個(gè)是多態(tài)。
2、
我們都知道,在Java中接口不能直接實(shí)例化。但是有的時(shí)候,我們會(huì)看到這種匿名內(nèi)部類(假象的所謂內(nèi)部類)實(shí)例化的代碼。如下:
綁定View對(duì)象的監(jiān)聽方法調(diào)用
View.setOnClickListetener(new OnClickListener()
{
@Override
public void onClick(View v)
{
}
}
);
OnClickListener是接口,在setOnClickListener()方法中卻new了這個(gè)接口?這個(gè)是怎么回事?不是說接口不能實(shí)例化么?嘿嘿,其實(shí)這個(gè)問題,本人也糾結(jié)了很久。后面終于摸清了大概了。
其實(shí)這是一種虛擬的實(shí)例化接口,可以理解為間接實(shí)例化接口。在這個(gè)setOnClickListener()方法中,傳入的重點(diǎn)是實(shí)現(xiàn)這個(gè)接口的onClick()方法,當(dāng)我們?cè)赩iew被點(diǎn)擊時(shí)這個(gè)方法會(huì)被調(diào)用,也就是會(huì)產(chǎn)生我們所需求的相應(yīng)的監(jiān)聽事件。那么在這個(gè)方法被調(diào)用之后,其實(shí)這個(gè)OnClickListener接口是不存在的。也就是說這個(gè)所謂的假象實(shí)例化其實(shí)是醉翁之意不在實(shí)例化接口而是在于OnClick()方法的實(shí)現(xiàn)。
上面這種是匿名內(nèi)部類的寫法,可以理解是一種簡化形式。事實(shí)上,它相當(dāng)于創(chuàng)建一個(gè)實(shí)現(xiàn)OnClickListener接口的類的對(duì)象,然后將對(duì)象作為參數(shù)傳入setOnClickListetener()方法。
舉個(gè)列子,上面的View對(duì)象綁定監(jiān)聽可以寫成另一種形式,如下:
class MyListener implements OnClickListener
{
@Override
public void onClick(View v)
{
.....
}
}
View.setOnClickListetener(new MyListener);
上面的監(jiān)聽綁定還可以寫成另一種形式:將View對(duì)象所在的類實(shí)現(xiàn)OnClickListener接口(implements OnClickListener),然后View.setOnClickListener(this),接著在這個(gè)View對(duì)象所在的類里直接調(diào)用實(shí)現(xiàn)接口的onClick()方法。其實(shí)也就是和第二種形式相類似。在這種綁定監(jiān)聽的方式中,就沒有所謂的實(shí)例化接口OnClickListener。
所以,在上面的所謂假象的實(shí)例化內(nèi)部接口,其實(shí)就是要達(dá)到實(shí)現(xiàn)接口覆蓋其抽象方法onClick()的功效,并不是所謂的實(shí)例化接口(這只是純粹的個(gè)人理解)。
再舉個(gè)列子:如與創(chuàng)建線程相關(guān)的Runnable接口,啟動(dòng)一個(gè)線程new Thread(r).start();參數(shù)r就是實(shí)現(xiàn)Runnable接口類型的對(duì)象。而關(guān)于參數(shù)r,我們可以這樣創(chuàng)建:
public Runnable r = new Runnable()
{
@Override
public void run()
{
...
}
}
注意,此處的Runnable是接口,而我們卻new了Runnable,那不就是直接實(shí)例化接口啦?其實(shí)不然,此處代碼的意思就是new了一個(gè)實(shí)現(xiàn)Runnable接口的匿名內(nèi)部類,然后new得到匿名內(nèi)部類的對(duì)象再向上轉(zhuǎn)型為它實(shí)現(xiàn)的接口(原始類型)。
這個(gè)是匿名內(nèi)部類。