Java 中extends與implements使用方法

來源:互聯網
上載者:User

初學Java語言, 代碼中的extends和implements讓我感到很迷惑,現在終於弄明白它們之間的區別和用法了。

//定義一個Runner介面<br />public inerface Runner<br />{<br /> int ID = 1;<br /> void run ();<br />}

 

//定義一個interface Animal,它繼承於父類Runner<br />interface Animal extends Runner<br />{<br /> void breathe ();<br />}

//定義Fish類,它實現了Animal介面的方法run()和breather()<br />class Fish implements Animal<br />{<br /> public void run () //實現了Animal方法run()<br /> {<br /> System.out.println("fish is swimming");<br /> }<br />public void breather()<br /> {<br /> System.out.println("fish is bubbing");<br /> }<br />}<br />//定義了一個抽象類別LandAnimal,它實現了介面Animal的方法。<br />abstract LandAnimal implements Animal<br />{</p><p> public void breather ()<br /> {<br /> System.out.println("LandAnimal is breathing");<br /> }<br />}<br />//定義了一個類Student,它繼承了類Person,並實現了Runner介面的方法run()。<br />class Student extends Person implements Runner<br />{<br /> ......<br /> public void run ()<br /> {<br /> System.out.println("the student is running");<br /> }<br /> ......<br />}</p><p>//定義了一個介面Flyer<br />interface Flyer<br />{<br /> void fly ();<br />}</p><p>//定義了一個類Bird,它實現了Runner和Flyer這兩個介面定義的方法。<br />class Bird implements Runner , Flyer<br />{<br /> public void run () //Runner介面定義的方法。<br /> {<br /> System.out.println("the bird is running");<br /> }<br /> public void fly () //Flyer介面定義的方法。<br /> {<br /> System.out.println("the bird is flying");<br /> }<br />}</p><p>//TestFish類<br />class TestFish<br />{<br /> public static void main (String args[])<br /> {<br /> Fish f = new Fish();<br /> int j = 0;<br /> j = Runner.ID;<br /> j = f.ID;<br /> }<br />}

 

介面實現的注意點:

a)實現一個介面就是要實現該介面的所有的方法(抽象類別除外)。
b)介面中的方法都是抽象的。
c)多個無關的類可以實現同一個介面,一個類可以實現多個無關的介面。


extends與implements的區別:



extends
是繼承父類,只要那個類不是聲明為final或者那個類定義為abstract的就能繼承,JAVA中不支援多重繼承,但是可以用介面來實現,這樣就用到了implements,繼承只能繼承一個類,但implements可以實現多個介面,用逗號分開就行了。


比如:




class A extends B implements C,D,E {}    (class 子類名 extends 父類名 implenments 介面名)

 

父類與子類繼承關係上的不同:

A a = new B(); 結果a是一個A類的執行個體,只能訪問A中的方法,那麼又和A a = new A();有什麼區別呢?

***********************************************************************************************

class B extends A
繼承過後通常會定義一些父類沒有的成員或者方法。
A a = new B();
這樣是可以的,上傳。
a是一個父類對象的執行個體,因而不能訪問子類定義的新成員或方法。

***********************************************************************************************

假如這樣定義:
class A

{
  
int i;
  
void f(){}
}
class B extends A

{
   
int j;
   
void f(){}       //重寫
   
void g(){}
}
然後:
B b = new B();
b就是子類對象的執行個體,不僅能夠訪問自己的屬性和方法,也能夠訪問父類的屬性和方法。諸如b.i,b.j,b.f(),b.g()都是合法的。此時b.f()是訪問的B中的f()


A a = new B();
a雖然是用的B的建構函式,但經過upcast,成為父類對象的執行個體,不能訪問子類的屬性和方法。a.i,a.f()是合法的,而a.j,a.g()非法。此時訪問a.f()是訪問B中的f()

***********************************************************************************************

A a = new B(); 這條語句,實際上有三個過程:
(1) A a;
將a聲明為父類對象,只是一個引用,未配置的空間
(2) B temp = new B();
通過B類的建構函式建立了一個B類對象的執行個體,也就是初始化
(3) a = (A)temp;
將子類對象temp轉換未父類對象並賦給a,這就是上傳(upcast),是安全的。
經過以上3個過程,a就徹底成為了一個A類的執行個體。
子類往往比父類有更多的屬性和方法,上傳只是捨棄,是安全的;而下傳(downcast)有時會增加,通常是不安全的。

***********************************************************************************************

a.f()對應的應該是B類的方法f()
調用建構函式建立執行個體過後,對應方法的入口已經確定了。
如此以來,a雖被上傳為A類,但其中重寫的方法f()仍然是B的方法f()。也就是說,每個對象知道自己應該調用哪個方法。
A a1 = new B();
A a2 = new C();
a1,a2兩個雖然都是A類對象,但各自的f()不同。這正是多態性的體現。

***********************************************************************************************

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.