日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

java 接口 實(shí)現(xiàn)和繼承關(guān)系

 hubimaso 2012-04-13

java 接口 實(shí)現(xiàn)和繼承關(guān)系

分類(lèi): JAVA 4750人閱讀 評(píng)論(4) 收藏 舉報(bào)

一。抽象類(lèi)

有時(shí)候,我們可能想要構(gòu)造一個(gè)很抽象的父類(lèi)對(duì)象,它可能僅僅代表一個(gè)分類(lèi)或抽象概念,它的實(shí)例沒(méi)有任何意義,因此不希望它能被實(shí)例化。例如:有一個(gè)父類(lèi)“ 水果(Fruit)”,它有幾個(gè)子類(lèi)“蘋(píng)果(Apple)”、“橘子(Orange)”、“香蕉(Banana)”等。水果在這里僅僅只是作為一個(gè)分類(lèi), 顯然水果的實(shí)例沒(méi)有什么意義(就好像一個(gè)人如果告訴你他買(mǎi)了一些水果但是卻不告訴你是蘋(píng)果還是橘子,你很難想象他到底買(mǎi)的是什么。)。而水果類(lèi)又要能被子 類(lèi)化,這就要求我們使用抽象類(lèi)(abstract class)來(lái)解決這個(gè)問(wèn)題。
在java中,通過(guò)在class關(guān)鍵字前增加abstract修飾符,就可以將一個(gè)類(lèi)定義成抽象類(lèi)。抽象類(lèi)不能被實(shí)例化。例如:
          定義抽象類(lèi)水果(Fruit)
          public abstract class Fruit {
                  ……
          }
           如果我們?cè)噲D用以下語(yǔ)句來(lái)獲得一個(gè)實(shí)例,將無(wú)法編譯成功。
           Fruit fruit = new Fruit();

而我們?nèi)匀豢梢詷?gòu)造水果類(lèi)的子類(lèi),如:
          子類(lèi)“蘋(píng)果(Apple)”
           public class Apple extends Fruit {
                   ……
           }
          子類(lèi)“橘子(Orange)”
           public class Orange extends Fruit {
                   ……
           }
這樣就達(dá)到我們的目的了。
抽象類(lèi)除了能象普通類(lèi)一樣可以擁有一般的屬性和方法,也可以擁有抽象方法(abstract method)。例如:
           抽象類(lèi)“形狀(Shape)”擁有抽象方法draw()。
           public abstract class Shape {
                  ……
                  public abstract void draw();
                  ……
           }
抽象方法與抽象的行為相對(duì)應(yīng),通常是這個(gè)行為對(duì)父對(duì)象沒(méi)有意義,而子對(duì)象有具體動(dòng)作。例如方法draw()對(duì)于類(lèi)Shape沒(méi)有意義,而類(lèi) Shape的子類(lèi)矩形(Rectangle)的方法draw()可以有實(shí)際的動(dòng)作(根據(jù)矩形的四個(gè)頂點(diǎn)畫(huà)出矩形的四個(gè)邊),子類(lèi)圓(Circle)的方法 draw()也可以有實(shí)際的動(dòng)作(根據(jù)圓心和半徑畫(huà)出圓周)。
抽象類(lèi)可以有抽象方法也可以沒(méi)有抽象方法;但是如果一個(gè)類(lèi)有抽象方法,那這個(gè)類(lèi)只能定義為抽象類(lèi)。
           如果按照以下代碼類(lèi)“形狀(Shape)”仍然擁有抽象方法draw(),但沒(méi)有定義為抽象類(lèi),將會(huì)編譯失敗。
           public class Shape {
                  ……
                  public abstract void draw();
                  ……
           }
抽象方法還有一個(gè)特點(diǎn)是,它強(qiáng)迫子類(lèi)要么仍然保持抽象性(即不具體實(shí)現(xiàn)該方法并仍然定義為抽象類(lèi)),要么具體表現(xiàn)出這個(gè)方法的行為(實(shí)現(xiàn)具體的動(dòng)作或者通過(guò)拋出UnsupportedOperationException異常來(lái)表明不支持該行為)。這樣也可以強(qiáng)化多態(tài)性。

 

 

 

二 接口

 

下面談?wù)劷涌冢╥nterface)。java語(yǔ)言使用關(guān)鍵字interface定義一個(gè)接口。接口也是抽象對(duì)象,它甚至比抽象類(lèi)更抽象。接口中的方法都是抽象方法。
一個(gè)接口可以繼承其他接口;一個(gè)類(lèi)通過(guò)關(guān)鍵字implements聲明要實(shí)現(xiàn)一個(gè)接口,并具體實(shí)現(xiàn)接口的方法。
           例如:有一個(gè)接口InterfaceA,

Java代碼
public   interface  InterfaceA {   
         void  methodA();   
}  
 
           類(lèi)ClassA實(shí)現(xiàn)接口InterfaceA。

Java代碼
public   class  ClassA  implements InterfaceA {   
          public   void  methodA() {   
               System.out.println( "methodA of ClassA implements InterfaceA" );   
         }   
}  
 
如果是抽象類(lèi)實(shí)現(xiàn)一個(gè)接口,那么抽象類(lèi)中可以不具體實(shí)現(xiàn)接口的方法(保持其抽象性),而由其子類(lèi)去實(shí)現(xiàn)。
           抽象類(lèi)ClassB實(shí)現(xiàn)接口InterfaceA,但是沒(méi)有具體實(shí)現(xiàn)方法methodA(),

Java代碼
public   abstract   class  ClassBS  implements InterfaceA{           }  
 
           子類(lèi)ClassBSub實(shí)現(xiàn)接口InterfaceA,但是沒(méi)有具體實(shí)現(xiàn)方法methodA(),

Java代碼
public   class  ClassBSub implements InterfaceA{   
         public   void  methodA() {   
              System.out.println( "methodA of ClassBSub the subclass of ClassB" );   
        }   
}  

 

接口和抽象類(lèi)顯著的共同點(diǎn)是接口和抽象類(lèi)都可以有抽象方法。
接口和抽象類(lèi)的不同點(diǎn)有:
           (1)抽象類(lèi)可以有實(shí)例變量,而接口不能擁有實(shí)例變量,接口中的變量都是靜態(tài)(static)的常量(final)。
           (2)抽象類(lèi)可以有非抽象方法,而接口只能有抽象方法。

 

java允許一個(gè)接口繼承多個(gè)父接口,也允許一個(gè)類(lèi)實(shí)現(xiàn)多個(gè)接口,而這樣的多繼承有上面提到的缺點(diǎn)馬?
答案是沒(méi)有,這是由接口的抽象性決定的。
正如前面介紹的,在接口中不能有實(shí)例變量,只能有靜態(tài)的常量,不能有具體的方法(包含方法體),只能有抽象方法,因此也就摒棄了多繼承的缺點(diǎn)。
對(duì)于一個(gè)類(lèi)實(shí)現(xiàn)多個(gè)接口的情況,因?yàn)榻涌谥挥谐橄蠓椒?,具體方法只能由實(shí)現(xiàn)接口的類(lèi)實(shí)現(xiàn),在調(diào)用的時(shí)候始終只會(huì)調(diào)用實(shí)現(xiàn)類(lèi)的方法(不存在歧義), 因此不存在多繼承的第二個(gè)缺點(diǎn);而又因?yàn)榻涌谥挥徐o態(tài)的常量,但是由于靜態(tài)變量是在編譯期決定調(diào)用關(guān)系的,即使存在一定的沖突也會(huì)在編譯時(shí)提示出錯(cuò);而引 用靜態(tài)變量一般直接使用類(lèi)名或接口名,從而避免產(chǎn)生歧義,因此也不存在多繼承的第一個(gè)缺點(diǎn)。
對(duì)于一個(gè)接口繼承多個(gè)父接口的情況也一樣不存在這些缺點(diǎn)。

請(qǐng)看以下示例。
            接口A:

Java代碼
public   interface  InterfaceA {   
         int  len =  1 ;   
         void  output();   
}  
 
            接口B:

Java代碼
public   interface  InterfaceB {   
           int  len =  2 ;   
           void  output();   
}  
 
            接口InterfaceSub繼承接口A和接口B:

Java代碼
public   interface  InterfaceSub  extends  InterfaceA, interfaceB {            }  
 
            類(lèi)Xyz實(shí)現(xiàn)接口InterfaceSub

Java代碼
public   class  Xyz  implements  InterfaceSub {   
         public   void  output() {   
                System.out.println( "output in class Xyz." );   
        }   
          public   void  outputLen( int  type) {   
                  switch (type) {   
                          case  InterfaceA.len:   
                                 System.out.println( "len of InterfaceA=." +type);   
                                  break ;   
                          case  InterfaceB.len:   
                                 System.out.println( "len of InterfaceB=." +type);   
                                  break ;   
                 }   
        }   
        public   static   void  main(String[] args) {   
               Xyz xyz=  new  Xyz ();   
               xyz .output();   
               xyz .outputLen();   
       }   
 

           以上代碼不存在什么問(wèn)題,但是如果試圖編寫(xiě)以下存在沖突的代碼,則會(huì)編譯失敗。

Java代碼
Xyz xyz =  new  Xyz();   
int  len = xyz.len;   
System.out.println(len);  

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多