Java基礎--繼承、抽象、接口


一、繼承

    1.概念

         把很多類的相同特徵和行爲進行抽取,用一個類來描述。讓多個類和這個類產生一個關係。這樣,多個類就可以省略很多代碼。這個關係就是繼承。java中用extends關鍵字表示。

    2.繼承的特點

         1):java中只能單繼承,沒有多繼承。

         2):java可以有多重(層)繼承。

    3.繼承的體系結構

        1):概念:多個具體的對象,不斷的向上抽取共享的內容,最終形成了一個體系。這個體系叫做繼承體系。

        2):繼承體系的學習和使用原則:

              a)學習頂層的內容。因爲他是整個體系的共性內容。

              b)創建子類使用。也就是使用底層的具體對象。

    4.繼承的好處:

         1)繼承的出現提高了代碼的複用性。

         2)繼承的出現讓類與類之間產生了關係,提供了多態的前提。

    5.子父類中的成員關係

       A:成員變量

           在子類方法中使用一個變量時:

           首先,在方法的局部變量中找這個變量,有則使用。

           否則,在本類中找成員變量,有則使用。

           否則,在父類中找成員變量,有則使用。

           否則,報錯。

       B:成員方法

           用子類對象使用一個方法時。

           首先,在子類中找這個方法,有則使用。

           否則,在父類中找這個方法,有則使用。

           否則,報錯。

    6.重寫和重載的區別?

        重載:在同一類中。方法名相同,參數列表不同。重載可以改變返回類型。

        重寫:在不同類中(子父類中)。方法聲明相同(返回類型,方法名,參數列表均相同)。

        重寫需要注意:

           1)子類方法的訪問權限要大於等於父類方法的訪問權限。

           2)靜態只能重寫靜態。但是這種情況一般不會出現。

     7.this和super的區別

          this:代表本類對象的引用。

          super:代表父類的存儲空間。

     8.final關鍵字(重點)

        1)最終的意思,可以用於修飾類,方法,變量。

        2)final修飾的類不能被繼承。

        3) final修飾的方法不能被重寫。

        4) final修飾的變量是一個常量。只能被賦值一次。

        5)內部類只能訪問被final修飾的局部變量。

     程序示例:   

<span style="font-size:14px;">class Person{ //定義一個父類Person
	String name;
	int age;
	Person(String name,int age){
		this.name =name;
		this.age=age;
		System.out.println("姓名: "+name+" 年齡: "+age);
	}
	//Person共有功能eat
	public void eat(){   
		System.out.println("eat");
	}
}
class Student extends Person{   //定義一個子類student繼承Person
	Student(String name,int age){
		super(name,age); //super關鍵字表示父類,因爲姓名和年齡在父類中進行了初始化動作,在這裏可以直接調用  
	}
	 //Student特有功能study
	void study(){  
		System.out.println("study");
	}
	//Student特有功能exam
	void exam(){
		System.out.println("exam");
	}
}
public class PersonExtends1 {
	public static void main(String[] args) {
     Student stu=new Student("qiao",23);
     stu.eat();
     stu.study();
     stu.exam();
	}
}</span>

  二、抽象類  

1.概念

        抽象就是從多個事物中將共性的,本質的內容抽取出來。

    2.特點

       1):抽象類和抽象方法都要用abstract進行修飾

       2):抽象類不能被實例化

       3):抽象類中不一定有抽象方法,但是,有抽象方法的類一定是抽象類。

    3.抽象類中數據的特點

       A:成員變量

            抽象類中可以有變量,也可以有常量。

       B:成員方法

            抽象類中可以有抽象方法,也可以有非抽象方法。

       C:構造方法

            抽象類是一個類,所以,它有構造方法。 雖然本身不能實例化。但是可以給子類實例化使用。

    4.抽象類中的問題

        1):抽象類中是否有構造方法?能不能被實例化?如果不能,爲什麼有構造方法?

               抽象類有構造方法。 抽象類不能被實例化。抽象類中的構造方法供子類實例化調用。

        2):抽象關鍵字abstract不可以和哪些關鍵字共存?

               a):private,私有內容子類繼承不到,所以,不能重寫。但是abstract修飾的方法,要求被重寫。兩者衝突。

               b):final,final修飾的方法不能被重寫。而abstract修飾的方法,要求被重寫。兩者衝突。

               c):static假如一個抽象方法能通過static修飾,那麼這個方法,就可以直接通過類名調用。而抽象方法是沒有方法體的,這樣的調用無意義。

        3):抽象類中可不可以沒有抽象方法?如果可以,這樣的類有什麼用嗎?

               抽象類可以沒有抽象方法。抽象類中沒有抽象方法的作用,只是爲了不讓別的類建立該抽象類對象。

      程序示例:

<span style="font-size:14px;">abstract class Person{
	//定義抽象方法run()
	abstract void run();
}
class Student extends Person{
	//實現抽象方法run()
	void run(){
		System.out.println("Run");
	}
}
public class Abstract1 {
	public static void main(String[] args) {
     Student stu=new Student();//創建Student實例對象
     stu.run();//調用Student的run()方法
	}
}</span>

三、接口

    1.概念

        當一個類中的方法都是抽象的時候,java提供了另一種表示方式,叫接口。

       用interface關鍵字表示。類與接口關係用implements表示。

    2.接口的成員特點

        A:成員變量

             是常量,默認修飾 public static final

        B:成員方法

             都是抽象的,默認修飾 public abstract

    3.關係
       A:類與類的關係

            是繼承關係。類與類只能單繼承,可以多重繼承。

       B:類和接口的關係

           是實現關係。類在繼承一個類的同時,可以多實現接口。

       C:接口和接口的關係

           是繼承關係。接口可以多繼承接口。

    4.接口的特點

         1):是對外暴露的規則

         2):是功能的擴展

         3):接口的出現降低耦合性。(耦合:類與類之間的關係、內聚:類完成功能的能力)

             編程規範:低耦合,高內聚。

         4):接口可以多實現。如:CPU和主板、筆記本的USB插口、插座

   

 四.抽象類和接口的區別

       

1.語法層面上的區別

  1)抽象類可以提供成員方法的實現細節,而接口中只能存在public abstract 方法;

  2)抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;

  3)接口中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;

  4)一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。

2.設計層面上的區別

  1)抽象類是對一種事物的抽象,即對類抽象,而接口是對行爲的抽象。抽象類是對整個類整體進行抽象,包括屬性、行爲,但是接口卻是對類局部(行爲)進行抽象。舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛。那麼在設計的時候,可以將飛機設計爲一個類Airplane,將鳥設計爲一個類Bird,但是不能將 飛行 這個特性也設計爲類,因此它只是一個行爲特性,並不是對一類事物的抽象描述。


     此時可以將 飛行 設計爲一個接口Fly,包含方法fly( ),然後Airplane和Bird分別根據自己的需要實現Fly這個接口。然後至於有不同種類的飛機,比

戰鬥機、民用飛機等直接繼承Airplane即可,對於鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這裏可以看出,繼承是一個 "是不是"的關

系,而 接口 實現則是 "有沒有"的關係。如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而接口實現則是有沒有、具備不具備的關係,比

如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個接口,不能飛行就不實現這個接口。


  2)設計層面不同,抽象類作爲很多子類的父類,它是一種模板式設計。而接口是一種行爲規範,它是一種輻射式設計。什麼是模板式設計?最簡

單例子,大家都用過ppt裏面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它們的公共部分需要改動,則只

需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動。而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更

新。也就是說對於抽象類,如果需要添加新的方法,可以直接在抽象類中添加具體的實現,子類可以不進行變更;而對於接口則不行,如果接口進行了

變更,則所有實現這個接口的類都必須進行相應的改動。


  下面看一個網上流傳最廣泛的例子:門和警報的例子:門都有open( )和close( )兩個動作,此時我們可以定義通過抽象類和接口

來定義這個抽象概念:

            

<span style="font-size:14px;">abstract class Door {
    public abstract void open();
    public abstract void close();
}</span>

    但是現在如果我們需要門具有報警alarm( )的功能,那麼該如何實現?下面提供兩種思路:

  1)將這三個功能都放在抽象類裏面,但是這樣一來所有繼承於這個抽象類的子類都具備了報警功能,但是有的門並不一定具備報警功能;

  2)將這三個功能都放在接口裏面,需要用到報警功能的類就需要實現這個接口中的open( )和close( ),也許這個類根本就不具備open( )和close( )

這兩個功能,比如火災報警器。

     從這裏可以看出, Door的open() 、close()和alarm()根本就屬於兩個不同範疇內的行爲,open()和close()屬於門本身固有的行爲特性,而

alarm()屬於延伸的附加行爲。因此最好的解決辦法是單獨將報警設計爲一個接口,包含alarm()行爲,Door設計爲單獨的一個抽象類,包含open和close

種行爲。再設計一個報警門繼承Door類和實現Alarm接口。


<span style="font-size:14px;">interface Alram {
    void alarm();
}
 
abstract class Door {
    void open();
    void close();
}
 
class AlarmDoor extends Door implements Alarm {
    void oepn() {
      //....
    }
    void close() {
      //....
    }
    void alarm() {
      //....
    }
}</span>




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