java基礎第9天


抽象類概述


抽象類的由來
  思考:一個公司中可能存在經理、程序員、銷售員等等,但有沒有員工呢?我說的不是員工的子類,而只是員工!我想你找不到吧!我也找不到這樣的東西!員工太抽象了,我們不需要它的實例,而只是需要它子類的實例。
  思考:雖然不需要員工的實例,但是否需要員工的引用呢?我們需要使用員工類的引用來指向它子類的實例。例如我們需要把所有員工子類的實例對象放到一個數組中,然後去調用每個員工子類對象的get月薪方法()。
  我們需要在員工類中定義get月薪方法(),但不知道怎麼去實現它。因爲不同的員工有不同的計算月薪的方式。所以這個方法只有具體的子類知道怎麼去實現。但員工必須要有這個方法的定義,因爲沒有這個方法的定義,就不能使用員工類的引用來調用子類的這個方法了(多態)。
  總結:
需要員工類的引用,但不需要員工類的實例對象;
員工類需要有get月薪方法(),但只需要定義不需要實現內容;
員工類用來作爲派生子類而用,子類需要重寫員工類的get月薪方法()


爲了讓使用者小心使用,我們需要在員工類中添加註釋如下:
不要創建本類的實例對象,本類是用來派生子類的模板;
可以創建本類的引用,但需要指向本類子類的實例對象;
本類的get月薪()方法只給出定義,但沒有給出實現內容;
子類需要去重寫get月薪()方法;
在員工類中定義get月薪方法的目的是爲了使用員工類的引用時可以調用這個方法完成多態調用。


但使用者不聽話怎麼辦!!!


2抽象類(abstract)
定義:具有一個或多個抽象方法的類必須聲明爲抽象類。
(1)只抽取了很多類的方法的聲明,爲了保證不出問題,方法聲明用abstract修飾。
(2)抽象類的特點
A:一個類如果有了抽象方法,那麼這個類必須是抽象類。抽象類裏邊可以沒有抽象方法。
   B:抽象類是不能夠被實例化的。不能夠創建對象的。但可以創建抽象類的引用。可以使用抽象類的引用來指向其子類的實例對象。抽象類就是用來派生子類的。


C:如果一個類繼承抽象類,那麼,它要麼實現抽象類中的所有抽象方法,
  要麼本身也是抽象類。
(3)抽象類的成員特點:
A:成員變量:子類可以直接繼承抽象類中的成員變量。(抽象類中的成員變量可以和以前是一樣的)
            B:成員方法:抽象類中分爲兩種方法,一種是抽象方法,


           抽象方法只給定方法的聲明部分,但沒有方法體。
   抽象方法需要使用abstract關鍵字來修飾。public abstract void fun();
        抽象方法沒有方法體,以一個分號來代替方法體內容。
            抽象方法只給出了“做什麼”,而沒給出“怎麼做”。
                      抽象方法是沒有完成的方法,需要在子類中完成“怎麼做”。


            一種是普通的方法。可以被子類直接繼承使用。
C:構造方法:抽象類不能被實例化,那麼它有構造方法嗎?抽象類是class,那麼它就有構造方法。
    它的構造方法有用嗎?有,爲了讓子類實例化的時候使用。
(4)舉例:教師舉例,學生舉例,員工舉例
(5)抽象類的相關問題:
A:抽象類中是否有構造函數?參照(3)裏面的C。
B:抽象關鍵字abstract不可以和哪些關鍵字共存?
**private
***私有的,外部直接無法訪問。
**static
***那麼這個時候抽象方法就可以可以通過類名調用,但是這樣是沒有意義的。
**final
***final修飾的方法不能被重寫。所以它和abstract衝突。
C:抽象類中可不可以沒有抽象方法?
**可以。防止其他類創建該類對象。
3抽象類與非抽象類的比較


  抽象類可以有構造器、屬性、非抽象方法、靜態方法,就是正常的類可以有什麼它就可以有什麼,而且抽象類還可以有抽象方法。
抽象類唯一不能有的就是一樣東西:實例對象


接口(interface)


(1)接口的由來:當一個類中的方法都是抽象的時候,你沒必要定義爲抽象類,
              定義爲接口就可以了。
(2)解決了java中只能單繼承的問題。(對多繼承進行了優化)
A:類與類:只能是單繼承。
B:接口與接口:可以是單繼承,也可以是多繼承。
C:類與接口:可以是單實現,也可以是多實現。
(3)成員特點:
A:只有成員變量和成員方法。
B:成員變量 默認修飾符 public static final
**int x = 20;
**其實是這樣的 public static final int x = 20;
C:成員方法 默認修飾符 public abstract
**void show();
**其實是這樣的 public abstract void show();
建議:自己手動加上修飾符。
(4)接口特點:
A:接口是對外暴露的規則
B:接口是功能的擴展
C:接口降低了程序的耦合性。
**內聚(自己實現功能的能力) 
**高內聚,低耦合。
舉例:主板和CPU,USB接口,電源插座。
D:擴展說了下接口的理解
**狹義的理解就是java中的接口。
**廣義的理解就是:任何定義的規範都是接口。
(5)接口和抽象類的區別:
A:抽象類只能被單繼承;接口可以被多實現。
B:抽象類中的成員:成員變量:可以是常量,也可以是變量。
  成員方法:可以是抽象的,也可以是非抽象的。
  構造方法:雖然不可以創建對象,但是可以給子類實例化用。
  接口中的成員:成員變量:只能是常量。默認修飾符 public static final
成員方法:只能是抽象的。默認修飾符 public abstract
C:抽象類中定義的是體系結構中的共性的內容。
  接口中定義的是對象的擴展功能。
D:抽象類被繼承表示的是:"is a"的關係。xx是yy中的一種。
  接口被實現表示的是: "like a"的關係。xx像yy中的一種。
(6)接口的練習1 學生(Student)、老師(Teacher)和菸民(Smoker)2 PCI設置、  網卡、聲卡3 形狀(shape)、矩形(Rectangle)、圓(Circle)
學生:Student


A:屬性:學號,姓名,年齡 
B:方法:學習(study),喫飯(抽象eat),抽菸或者不抽菸?(合適嗎)


發現:在學生中定義抽菸的方法不合適。所以呢,我們另外用一個類來定義抽煙的方法。
     但是發現,如果用一個類描述抽菸的功能後,SmokeStudent是不能繼承多個類的。
     這個時候,我們又得重寫思考了。發現,抽菸的學生像一個抽菸的機器,所以,
     我們定義一個接口來放抽菸這個功能。
        interface Smoking
{
public abstract void smoking();
}

  描述的是抽菸的學生:SmokeStudent extends Student implements Smoking


SmokeStudent ss = new SmokeStudent();
ss.eat();
ss.study();
ss.smoking();

 老師:Teacher
A:屬性 教師編號,姓名,年齡
B:方法 教書(teach),喫飯(喫飯eat),抽菸或者不抽菸?(合適嗎)


發現:在老師中定義抽菸的方法不合適。所以呢,我們另外用一個類來定義抽煙的方法。
     但是發現,如果用一個類描述抽菸的功能後,SmokeTeacher是不能繼承多個類的。
     這個時候,我們又得重寫思考了。發現,抽菸的老師像一個抽菸的機器,所以,
     我們定義一個接口來放抽菸這個功能。
        interface Smoking
{
public abstract void smoking();
}

 描述的是抽菸的老師:SmokeTeacher extends Teacher implements Smoking
SmokeTeacher st = new SmokeTeacher();
st.eat();
st.teach();
st.smoking();


 最後,我們發現,這個代碼還是存在着重複,比如說學生類和教師類中的屬性姓名,年齡及方法喫飯。
 所以,我們進一步向上抽取。來了一個Person類
 Person:屬性:姓名,年齡
         行爲:喫飯(抽象eat)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章