JAVA-面向對象


軟件公司做項目的流程:

 1 可行性分析

 2 需求分析,客戶要什麼?需要和客戶多次溝通,通過需求分析文檔的確認來確定。

 3 商業建模,大型項目需要。

 4 項目分析和設計。有些公司設計分概要設計和詳細設計。

 5 編碼(程序員的主業)

 6 測試(測試工程師)

 7 部署

 8 維護


面向對象(OO)的編程

   面向對象的編程思想的核心就是 一切皆是對象。

    面向對象和麪向過程是目前常見的編程思想,面向過程就是編程時以數據的流程(過程)作爲核心的編程。C語言是面對過程的代表,其它的主流都是面向對象的編程語言。

    面向對象以現實爲編程思想,現實是什麼樣子,代碼就怎麼實現。

   OOA - 面向對象的分析

   OOD - 面向對象的設計

   OOP - 面向對象的編程

   OOT - 面向對象的測試



  面向對象的核心概念

   類/對象/屬性(成員變量)/方法(成員方法)/構造方法

   重載(當一個類中寫上兩個或多個構造,自然形成構造方法的重載。重載就是類名同名但參數列表不同)

   重寫(當子類從父類中繼承下來的方法不足以滿足子類的要求,就需要對父類中的方法進行重寫/覆蓋,以滿足子類需求)

   封裝/繼承/多態


   Java的一些關鍵字:

     this和super、static、final、abstract等


   面向對象的三大基本特性: 封裝、繼承、多態。

    四大對象的基本特徵:封裝、繼承、多態、抽象。


  Java編程以類class作爲基本單位,寫代碼先寫class。


  是客觀世界中同一類事物的統稱,是對同一類事物的抽象,是概念,客觀世界中其實是不存在類的。

  對象就是客觀世界中的每一個具體事物。

  引用就是對象的標號,客觀世界中一般就是名字,代碼中就是變量名。


  寫程序要寫類,調用代碼時用對象。


  Scanner sc = new Scanner(System.in);     //創建對象

   Scanner是類, sc是引用, new Scanner() 是對象。


  屬性/方法和構造方法

   同一類事物的特徵/狀態 叫屬性(Field)/字段,也叫成員變量。

   同一類事物的行爲/功能 叫方法,也叫成員方法。

   構造方法就是創建對象時調用的,用於創建某類事物的對象。


  一個類的代碼由 屬性/方法和構造方法 組成,但屬性和方法可有可無


  類的語法:

    修飾符  class  類名{

      //屬性/方法和構造

    }

    修飾符可以不寫


  屬性(成員變量)的語法:(屬性是直接定義在類體中的變量)

    修飾符  變量類型(基本型和引用型)  變量名 = 初始值;

    修飾符可以不寫, = 初始值也可以不寫。

    如果屬性不給初始值,有默認值(變量不一定)。默認值和數組元素的一樣。

    整型都是0,浮點都是0.0,布爾都是false,字符型默認爲空格,引用類型都是null。

    默認值沒有實際的意義。


  方法(成員方法)的語法

    修飾符  返回值類型  方法名(參數列表) throws Exception(拋異常) { }

    修飾符可以不寫,返回值類型如果沒有返回值,寫void。

    throws Exception 可以不寫。參數列表如果沒有參數,寫() 。


  屬性和方法的區分:有()的是方法,沒有()是屬性。


  練習:

   寫一個類Point(點),裏面有兩個int類型的屬性x和y。(能javac不能java)

publilc class Point{

  int x;

  int y;

}



  創建對象的方法:

    new 構造方法(參數列表);     (new加構造方法(修飾符 類名(參數列表))組成對象)

    參數列表可以沒有,但是()必須有。

    new 後面只能跟構造方法,對象/引用後面可以用.調用屬性和方法。


  內存的區域劃分:

    內存分爲:代碼區(方法區)、字符串常量區、棧區/堆棧區stack、堆區heap等。


     代碼區存放代碼,主要是方法和構造方法。


     字符串常量區主要放各種字符串常量,就是""格式的字符串。


     棧區存放各種局部變量,包括方法的參數。特點的是後進先出。


     堆區是一大片內存,new的東西全部在堆區。


   C/C++程序員用指針操作內存,Java程序沒有指針,Java程序員不需要管內存的事情。

   JVM處理內存。 new 可以分配堆內存(創建對象就是在堆中開闢內存空間),內存回收由JVM啓動gc回收垃圾。



   Point p = new Point();不是一個語句,由3個語句組成:

   1 Point p 會在棧內存中放一個變量p進去。

   2 new Point() 會在堆內存中創建一個新的Point對象,裏面有x和y,值爲0。

   3 = 就是賦值,把對象的首地址賦值給p。


  練習:

   寫一個TestPoint類,寫主方法,然後創建一下Point對象,再把座標設置1,2。

然後打印一下點的座標。



  方法有三要素: 返回值類型、方法名、參數列表。


    方法名就是方法的名稱,符合標識符的規則即可。

    參數列表就是傳入方法的數據,比如:算兩個整數的加法,需要參數--2個加數。

              返回值類型就是方法傳出的數據(數據的類型),比如:算兩個整數的加法,需要返回結果。

              方法中如果需要返回,使用return關鍵字。


   public int add(int a,int b){

     return a+b;

   }


  練習:

   在Point中加上兩個方法,上下移動和左右移動。

   up()   - y發生改變

   left() - x發生改變

   並且在TestPoint中調用,向上移動2個座標,並且先向右移動3個座標。並且打印新的座標。


  構造方法 - 用於創建對象的代碼,一般都寫初始化的代碼。


  因爲寫的是類,調用的時候要用對象,如何由類得到對象呢? new + 構造方法。


  類都需要實例化成對象,因此,每個類都是必須有構造方法。


  JVM針對構造方法的機制: 如果類中沒有定義構造方法,系統會自動加一個無參數的構造方法;如果寫了構造方法,系統不再添加,因爲已經有了。


  構造方法的語法:

    修飾符  類名(參數列表) throws Exception{


    }

   修飾符和throws可以不寫。

   public Point(){ }


  構造方法和方法的兩大區別:

   1 方法有返回值,構造方法沒有返回值,包括void也沒有。

   2 方法名可以自定義,構造名和類名必須一致。

   在同一個類中,構造方法可以寫多個,但要求參數列表必須不同。(重載)


  面向對象的代碼彙總:

   public class Point{    //類

     屬性:     int age;

     構造方法: public Point(){  }

     方法:    public String test(int a)

                   { return "hello"; }

   }


   public class TestPoint{

      main(){

        Point p = new Point(); //構造方法的調用(創建對象)

        p.age = 30; //屬性

        String s = p.test(3);//方法

      }

   }

  作業:

    1 寫一個Student類,屬性:姓名/學號/年齡;構造寫兩個;方法寫三個: 獲取學生姓名的,修改學生姓名的,顯示學生信息(包括姓名/學號和年齡)。然後寫一個TestStudent類測試。

    2 寫一個商品Product類,屬性:編號、名稱和價格;構造寫兩個;方法寫三個:修改價格,顯示商品信息,比較兩個商品價格的高低(高/低/相等)。然後寫一個TestProduct類測試。





寫一個類(名詞性質),類中包括:

 public class 類名{

   屬性;

   構造方法;

   方法;

 }

 調用類中, new 構造方法() 可以得到對象,用對象/引用. 調用裏面的屬性和方法。 new一下,點一下。

 Product類的方法:

   public void setPrice(double nPrice){

     if(nPrice<0){

       System.out.println("價格錯誤,修改失敗");

     }else{

       price = nPrice;

     }

   }


/*

比較價格

*/

   public int comPrice(Product p){

     if(price>p.price){

       return 1;

     }else if(price==p.price){

       return 0;

     }else{

       return -1;

     }

   }


 this關鍵字


  所有的屬性變量不能重名,在同一區域的局部變量不能重名,但屬性和局部變量可以重名。

  在局部變量的作用區域之外,變量名代表屬性,

  在局部變量的作用區域之內,代表局部變量,如果想使用屬性,需要this. 調用。


  在構造方法中,可以用this()調用本類的其它構造。this()必須放在構造的第一行。


  this.可以調用本類的屬性和方法;this()可以調用本類的構造。


  this()可以實現構造代碼的複用。

  代碼複用是軟件開發中最常見的一種方式,就是代碼只寫一次,其它地方都是調用。

  其實,我們所有的API都是代碼複用。


重載 - Overload

  當在一個類中,寫上兩個或者更多的構造時,自然形成了構造方法的重載。重載就是同名但參數不同。

  重載的特點:

        相同的方法名稱,不同的參數列表,返回類型最好相同。

  重載的好處:

        就是讓調用者更方便,只需要記住一個方法名就可以了。重載不會簡化代碼量。

       不是所有的方法都需要重載,只有執行相似功能的方法纔可以重載。



Java參數傳遞


  java中的方法可以傳遞參數,參數的傳遞方法就是值傳遞


  參數有形參和實參,定義方法時寫的參數叫形參,    真正調用方法時,傳遞的參數叫實參


  調用方法時,會把實參傳遞給形參,方法內部其實是在使用形參。



  參數傳遞的步驟:

   1 分配實參的空間,基本類型在棧中賦值,引用類型變量在棧中,指向堆中的對象。

   2 傳遞參數其實就是在棧中分配形參的空間,然後把棧中實參的值複製過來。

   3 在方法中使用形參,方法結束形參出棧(消失),只剩下實參。


方法的遞歸

  方法自己調用自己就叫遞歸。

  遞歸有可能會大幅簡化代碼的編寫。

  遞歸要考慮性能問題,有些時候可以使用循環而不是遞歸。

  遞歸的使用原則:

  1 必須有退出條件。

  2 必須使問題變簡單,而不是複雜化。


遞歸實例:

  public class TestN{

    public long f(long n){ //遞歸

      if(n == 1) return 1;

      return n*f(n-1);

    }

  public static void main(String[] args){

    TestN tn = new TestN();

    long res = tn.f(20);

    System.out.println(res);

  }

}


 int a =2 ;int b = 3; //不借助其它變量交換a和b

 a = a+b;// a=5 b=3

 b = a-b;// a=5 b=2

 a = a-b;// a=3 b=2




 封裝 - 代碼如果不做限制,很多屬性值是無效的。封裝就是爲了保證屬性值有效的技術。


  封裝的步驟:

   1 先private(私有)修飾屬性(常量不用私有),讓屬性在類外不能被調用,避免類外的賦值。

     另外要給屬性一個合理的初始值。

   2 寫public的方法對屬性進行操作,一般都是set方法(寫入)和get()方法(讀取)。

   3 構造裏面不要賦值,要調set方法賦值。


  雖然封裝已經很嚴格,但是反射可以打破封裝。



----------------------------------------------------------------------------------------------------------------------------------------

今天內容:

   (1)static關鍵字

   (2)繼承

   (3)訪問控制

   (4)final關鍵字


1.static關鍵字(重點)

1.1 基本概念

   通常情況下,屬性和方法都屬於對象層級,訪問屬性和方法時需要先創建對象再訪問,

   每個對象都擁有自己獨立的屬性信息,

   但當使用static關鍵字修飾屬性後,該屬性就不再隸屬於對象層級,而是提升類層級,被整個類創建的所有對象共享。


   對於static(靜態的)修飾的屬性和方法來說,

   雖然可以使用對象./類名.進行訪問,但是絕大多數情況下都建議使用類名.訪問。

   static關鍵字可以修飾屬性/方法/語句塊。


1.2 使用方式

對屬性而言:

(1)對於非靜態屬性(無static)來說,每個對象都獨立擁有一份,只能通過各個對象通過對象.訪問,不能使用類名.訪問

(2)對於靜態屬性來說,該類型的所有對象共享同一份,可以通過對象./類名.訪問(兩種皆可,一般用類的多)。

對方法而言: 

(3)非靜態方法中可以訪問靜態屬性,也可以訪問非靜態屬性。

(4)靜態方法中只能訪問靜態屬性,不能訪問非靜態屬性


如:

/*

詳細解釋this.的作用效果

*/

   class A{                   //類A

      public void show(){   // => public void show(A this)   成員方法

      }


      public static void main(String[] args){           //主方法

            A a = new A();  // => 創建對象,調用構造方法

            a.show(); // => show(a);   對象調用方法  從系統底層來說是將對象當作實參調入方法之中,對應於方法定義來說是將對象調入方法定義中作爲形參。

      }

   }


1.3 類加載的方式(瞭解)


   類中使用static修飾的屬性/方法/語句塊都是隨着類的加載而準備就緒,其中類加載的主要方式有:

   (1)當創建對象時會加載類信息。

   (2)當使用類名.訪問static修飾的屬性/方法/語句塊時會加載類信息。

   (3)使用Class.forName()可以加載類信息(以後講到)     


注意:

   只有當該屬性/方法/語句塊隸屬於類層級被多個對象所共享時才能加static,否則不要隨便加static關鍵字。


1.4 構造塊和靜態語句塊(瞭解)

   完成構造方法之前的操作,例如調用數據庫、接入網絡什麼的。

   在類體中使用{}括起來的語句塊,叫做構造塊,每次創建對象時都會執行一次構造塊。

   在類體中使用static{}括起來的語句塊,叫做靜態語句塊,只在類加載時執行一次。


1.5 單例設計模式

(1)基本概念

   在某些特殊場合中,某個類有且只能有一個對象,這樣的類叫做單例類。

   使用單例類編程的模式就叫做單例設計模式


(2)實現方法

   a.私有化構造方法。

   b.創建並提供一個本類類型的對象,使用private和static修飾。

   c.提供一個公有的,使用static修飾的get方法負責返回本類對象。   


public class Singleton{


  //private static Singleton s = new Singleton();//餓漢型   創建並提供一個本類類型的對象,

                                                             用private static 來修飾

  private static Singleton s;   //懶漢型


  private Singleton(){     //私有化構造


  }

  public static Singleton getInstance(){   //提供一個公有化的   用static修飾的get方法來   返回本類類型。

    //return s ;

    if(null == s){

      s = new Singleton;

    }

    else{

      retutrn s;

    } 

  }

}




今天內容:

   (1)繼承

   (2)訪問控制

   (3)final關鍵字

   (4)對象創建的過程

   (5)多態


1.繼承

1.1 繼承的由來

學生類

   屬性:學號、姓名、年齡

   行爲:學習、吃飯、娛樂

教師類

   屬性:工號、姓名、年齡

   行爲:講課、吃飯、娛樂


   由上面的類可知,有些屬性和行爲是完全相同的,此時就可以將相同的屬性和行爲提取出來封裝到另外一個類中,叫做Person類,讓學生類和教師類繼承Person類即可。


Person類

   屬性:姓名、年齡

   行爲:吃飯、娛樂

學生類 繼承 Person類

   屬性:學號

   行爲:學習

教師類 繼承 Person類

   屬性:工號

   行爲:講課


1.2 基本概念


   繼承就是指從現有類中派生出新類,新類可以吸收現有類中的屬性和行爲,還可以增加自己獨有的屬性和行爲,從而實現代碼的複用。

   在java語言中使用 extends 來表達繼承關係。

如:

   class Student extends Person{}

   其中Student類 叫做 子類/派生類

   其中Person類 叫做 父類/基類/超類


1.3 注意事項

(1)子類可以繼承父類的主要內容有:

    a.可以繼承父類中的屬性,包括私有屬性。

    b.可以繼承父類中的方法,不包括 私有方法 和 構造方法

(2)當創建子類對象時,會自動調用父類中的無參構造方法,如果希望調用父類中的有參構造方法,則需要使用super關鍵字。

   無論子類中是否自定義構造方法,都會自動調用父類中的無參構造方法,用於初始化子類對象中的父類子對象。

(3)java語言中不支持多繼承,也就是說一個子類只能有一個父類,但一個父類可以有多個子類

(4)並不是兩個類中有相同的屬性和方法時,就一定可以繼承,必須滿足條件:子類 is a 父類時,才能使用繼承關係


1.4 super關鍵字的使用

(1)基本概念

    this關鍵字表示本類對象,可以使用this.來訪問本類和父類的屬性和方法。

    super關鍵字表示父類對象,可以使用super.來訪問父類中的屬性和方法。

(2)使用方式

    在構造方法中使用this()表示 調用本類的 構造方法,要求必須在構造方法的第一行出現

    在構造方法中使用super()表示 調用父類的 構造方法,要求必須在構造方法中第一行出現     

    this()和super()不可能同時出現,如果構造方法中啥也沒寫,則自動添加super()。


1.5 方法的重寫/覆蓋(override)


(1)方法重寫的由來

    當子類從父類中繼承下來的方法不足以滿足子類的需求時,就需要對父類中的方法進行重寫/覆蓋,來滿足子類的需求。


(2)方法重寫的要求

   a.要求方法名、參數列表以及返回值類型都相同。

   b.要求子類重寫方法的訪問權限不能比父類的方法小。

   c.要求子類重寫的方法不能拋出更大的異常。

   d.static修飾的方法重寫以後還是static的。


1.6 繼承的作用

  (1)實現了代碼的複用,並且提高了程序的擴展性和可維護性。

  (2)繼承是多態的前提條件。


2.訪問控制

2.1 常用的訪問控制符

   public - 表示公有的

   默認方式 - 表示默認的訪問權限

   protected - 表示保護的

   private - 表示私有的


2.2 訪問控制符對應的訪問權限

   訪問控制符   本類內部       子類      同一個包中的其他類      其他包中的類

--------------------------------------------------------------------------

    public        ok            ok               ok                 ok

    默認方式      ok            no               ok                 no

    protected     ok            ok               ok                 no

    private       ok            no               no                 no


總結:

    對於public修飾的屬性/方法來說,無論在哪裏都能訪問。

    對於private修飾的屬性/方法來說,只能在本類內部訪問,其他都不能訪問。

    一般來說,屬性都使用private修飾,而方法都使用public修飾。


2.3 包

   包本質就是文件夾/目錄,用於存放不同的java文件,可以避免文件同名而引發的錯誤,也可以對文件進行歸類,便於管理。

   定義包的語法格式是:

       package 包名;

       package 包名1.包名2.包名3....;  用於實現目錄的嵌套。


3.final關鍵字

3.1 基本概念

  final 翻譯爲 最終的,表示不可更改的意思。

  final關鍵字 可以修飾 類/方法/屬性。


3.2 使用方式


   final關鍵字修飾類 表示該類不能被繼承(斷子絕孫類),如:String類和System類、Math類,該方式的作用在於避免濫用繼承。


   final關鍵字修飾方法 表示該方法不能被重寫,該方式的作用在於避免濫用重寫。

        該方法可以被繼承。


   final關鍵字修飾屬性 表示該屬性必須要被初始化,不能依賴默認方式初始化,而一旦初始化完畢之後則不能更改,

        該方式的作用在於避免屬性值的意外修改。


3.3 final修飾屬性可以初始化的位置有:

   (1)在定義屬性的同時指定初始值。

   (2)在構造方法中指定初始值,但要求所有自定義構造方法中都要進行初始化。

   (3)在構造塊中進行初始化。 


4.對象創建的過程

4.1 單個類創建對象的執行過程

  (1)將硬盤上的.class文件加載到內存中,該過程叫做類加載。

  (2)在類加載的過程中自動加載靜態成員,包括靜態屬性和靜態方法以及靜態語句塊。

  (3)在加載的過程中先執行靜態語句塊。

  (4)執行完畢靜態語句塊之後執行構造塊(先父類後子類)。

  (5)再執行構造方法,也就是執行構造方法體中的語句(先父類後子類) 。 


4.2 單個類創建對象時屬性的賦值次序

  (1)執行靜態語句塊中屬性的賦值。

  (2)執行屬性的定義以及初始化語句。

  (3)執行構造塊中的語句。

  (4)執行構造方法體中的語句。

  (5)執行main方法創建對象後的語句。


作業:

   設計一個Girl類,屬性有:姓名、年齡以及是否有男朋友,行爲有:顯示所有屬性信息。

   設計一個Teacher類,屬性有:姓名、年齡以及薪水,行爲有:顯示所有屬性信息。

   先分別實現上述兩個類,再將共性提取出來爲一個Person類,修改上述兩個類繼承自Person類,在Gir類和Teacher類中實現對顯示屬性信息方法的重寫。





今天內容:

   (1)對象創建的過程

   (2)多態

   (3)抽象類

   (4)接口


1.對象創建的過程

1.1 單個類對象創建的過程

   (1)將硬盤上的.class文件加載到內存中,這個過程就叫類的加載。

   (2)執行靜態語句塊,隨着類的加載而準備就緒。

   (3)執行構造塊。

   (4)執行構造方法體。


1.2 父子類對象創建的過程

   (1)將硬盤上的.class文件加載到內存中,這個過程就叫類的加載。

   (2)先加載父類,執行父類的靜態語句塊。

   (3)再加載子類,執行子類的靜態語句塊。

   (4)創建父類子對象,對父類子對象中的屬性進行初始化,執行父類的構造塊。

   (5)執行父類的構造方法體,實現父類子對象的創建過程。

   (6)創建子類對象,對子類對象中的屬性進行初始化,執行子類的構造塊。

   (7)執行子類的構造方法體,實現子類對象的創建過程。


對象創建的過程(new XX()):

   1 JVM去硬盤中找class文件,然後讀入內存。

   2 進行類加載,先加載父類,後加載子類,同時執行分配static屬性的內存空間,執行static語句塊。

   3 給父類和子類的非靜態屬性分配內存空間,清空屬性或清0。

   4 執行父類屬性的初始化語句(如果聲明的同時進行了賦值),否則就還是空或0。

   5 執行父類的語句塊。

   6 執行父類的構造。

   7 執行子類屬性的初始化語句(如果聲明的同時進行了賦值),否則就還是空或0。

   8 執行子類的語句塊。

   9 執行子類的構造。




2.多態(重中之重)

2.1 基本概念

   多態就是指同一種事物具有多種不同的形態。

Java中有幾種多態:

   1 基本類型的多態 -- 本質就是基本類型的自動類型轉換和自動裝箱/解箱。(不是通常指的多態)

   2 方法多態  -- 方法的重寫和方法的重載

   3 引用類型的多態 -- 本質就是引用類型的自動類型轉換(子類對象自動轉父類)

     也就是父類的引用指向了子類的對象,用父類的類型可以傳入父類和子類的對象。父類引用可以表示父類對象和所有子類的對象。


   通常指的多態就是引用類型的多態。多態最大的作用就是: 設計方法時,可以用父類的類型代表父類和子類的所有對象


如:

   byte b = 4;  short s = 4;  int i = 4;

   寵物:貓/狗/魚/烏龜/兔子/小強/... ...


2.2 語法格式

   父類類型 引用名 = new 子類類型();


   在編譯階段引用是父類類型的,但是程序運行起來之後卻是子類類型的,最終調用的方法也是子類中重寫的方法,從而實現多態。


2.3 多態的效果

   (1)當使用父類引用指向子類對象時,父類引用只能調用父類中的方法,不能直接調用子類中的方法,因爲在編譯階段就報錯。

   (2)當希望父類引用能調用子類的方法時,需要對父類引用進行強制類型轉換,再調用。


2.4 父子類型之間的轉換

   子類類型向父類類型轉換時,只需要自動類型轉換即可。

   父類類型向子類類型轉換時,需要進行強制類型轉換。

   引用類型的轉換必須發生在父子類之間,否則編譯階段報錯,而且父類引用必須轉換爲真正指向的子類對象類型,否則在運行階段拋出異常,也就是產生錯誤。

   當需要發生強制類型轉換時,應該先使用instanceof來判斷引用名指向的真正類型是否和要轉換的目標類型相同,如果是則返回true,此時放心強轉,否則不要進行強轉。

如:

   if(ps instanceof Student){   如果成立則返回true,否則返回false。

      ... ...

   }


2.5 多態的作用

如:

   public void show(){}   - 打印學生的所有信息

   public void show(){}   - 打印老師的所有信息

   public void show(){}   - 打印工人的所有信息


   public void show(Student s){}

   public void show(Teacher t){}

   public void show(Worker w){}


解析:

   Person p = new Student();

   Person p = new Teacher();

   Person p = new Worker();


   public void show(Person p){

      p.print();

   }


調用:

   Student s = new Student();

   show(s);                       => Person p = s;  => p.print() => Student類print

   Teacher t = new Teacher();

   show(t);                       => Person p = t;  => p.print() => Teacher類print

   Worker w = new Worker();

   show(w);                       => Person p = w; => p.print() => Worker類print


   多態的主要作用在於屏蔽不同子類對象之間的差異性,從而寫出通用的代碼,實現通用的編程效果,也便於程序後續的維護和擴展性。


3.抽象類

3.1 基本概念

  抽象類就是指使用abstract關鍵字修飾的類。

  抽象類不能實例化對象/創建對象/構造對象,但可以被繼承。其意義就在於被繼承。


3.2 抽象方法

  抽象方法就是指使用abstract關鍵字修飾的方法,並且該方法沒有方法體,用分號結尾。

  語法格式:

      訪問控制符 abstract 返回值類型 方法名稱(形參1,形參2,...);


3.3 抽象類和抽象方法之間的關係

  (1)抽象類可以沒有抽象方法,也可以有抽象方法。

  (2)擁有抽象方法的類必須被聲明爲抽象類。

  (3)抽象類中可以有普通/靜態的方法。


3.4 抽象類的作用

  抽象類的主要作用在於被繼承,而子類一旦繼承抽象類之後就必須重寫抽象類中的抽象方法,否則子類也變成抽象類。 


注意:

   抽象類雖然不能創建對象,但是有構造方法,爲了子類創建對象時調用。


abstract 不能和final、static同時出現。


4.接口

4.1 基本概念

   黃金 屬於金屬,黃金屬於貨幣,在java語言中支持單繼承,因此黃金不能同時繼承金屬和貨幣,那麼怎麼辦呢?

   在java中引出接口的概念,一個類可以同時實現多個接口。

   定義類使用class關鍵字,繼承類使用extends關鍵字。

   定義接口使用interface關鍵字,實現接口使用implements關鍵字。

Java的接口用於解決多重繼承問題。接口一般用於定義規範,交給子類實現。

4.2 注意事項

   (1)接口中的屬性必須且只能是public static final,不寫自動添加。

   (2)接口中的方法必須且只能是public abstract,不寫自動添加。


4.3 類、接口之間的繼承關係

    類和類之間的繼承     單繼承    使用extends關鍵字

    類和接口之間的繼承   多繼承    使用implements關鍵字

    接口和接口之間的繼承 單繼承    使用extends關鍵字


注意:

    對於默認訪問方式的屬性來說,在其他包的子類中是不能直接訪問的,但是在同一個包中的子類是可以訪問的。    







複習:

1.對象和類的基本概念

  對象就是個東西,萬物皆對象。

  無論是何種對象,都會有  屬性和行爲。


  將對象的共性提取出來組成一個類,類中封裝描述屬性的成員變量,描述行爲的成員方法。

  類是一種用戶自定義的引用數據類型。


2.類的定義

  訪問修飾符 class 類名{

       訪問修飾符 數據類型 變量名 = 初始值;

       訪問修飾符 返回值類型 方法名(形參列表){ 方法體; }

  } 

如:

  public class Person{

     private String name;

     public void show(){}

  }


3.創建對象

  類類型 引用變量名 = new 類類型();


4.構造方法

  class 類名{


      訪問修飾符 類名(形參列表){ 構造方法體; }

  } 


  如果一個類中沒有自定義構造方法,則系統會自動提供一個無參的默認構造方法。

  如果一個類型中出現了構造方法,無論是否有參數,系統都不在提供默認構造方法。


5.方法的重載

   在同一個類中,方法名相同,參數列表不同,返回值類型最好相同。

   調用者使用非常方便。

   System.out.println(char); ... ...


6.this關鍵字

   Person p1 = new Person();

   Person p2 = new Person();


   p1.show();  => show(p1);   

   p2.show();  => show(p2);


   當形參變量名和屬性完全相同時,需要使用this.來進行區分

   this() - 表示調用本類的構造方法


7.封裝

  (1)私有化屬性;  (2)提供公有的get/set方法  (3)在構造方法中使用get/set方法


8.static關鍵字

   static關鍵字可以修飾屬性/方法,從對象層級提升到類層級,雖然可以使用對象.調用,但是推薦使用類名.調用。

   static修飾的方法中 能訪問static修飾的屬性和方法,但是不能訪問非static修飾的。

   非static修飾的方法中 可以訪問static修飾的,也可以訪問非static修飾的


   單例設計模式 - 懶漢式/餓漢式


9.繼承

   繼承就是從現有類中派生出新的子類,子類吸收現有類的屬性和方法,還可以增加新的屬性和行爲,表示個性.

   使用extends關鍵字進行繼承,java中支持單繼承,不支持多繼承。

   Student extends Person


   super() - 調用父類的無參構造方法

   super(實參) - 調用父類中的有參構造方法

   必須放在構造方法中的第一行,不可能和this同時出現


   this.調用本類的屬性/方法以及從父類中繼承來的屬性和方法

   this()


   super.調用父類的屬性/方法

   super() 


   方法的重寫 

       要求方法名相同、返回值類型相同、參數列表也相同。

       不能拋出更大的異常

       權限不能更小


10.final關鍵字

   final修飾類/方法/屬性。


   final修飾的屬性可以初始化的位置:定義/構造方法中/構造塊


11.多態

   父類類型 引用名 = new 子類類型();


   子類類型轉換到父類類型自動轉換完成

   父類類型到子類類型的轉換 需要 進行 強制類型轉換,進行判斷

   父子類之間的轉換

   instanceof 進行判斷    true  false


   多態屏蔽不同子類之間的差異性,實現了通用的編程


12.抽象類

   使用abstract關鍵字修飾的類  不能創建對象,但是有構造方法

   使用abstract關鍵字修飾方法,並且沒有方法體,使用分號結尾。


   被繼承,要求子類去實現一些方法。


13.接口

   用於解決多繼承的問題。

   interface關鍵字    implements


   類  繼承  類   單繼承   extends

   類  繼承  接口  多繼承  implements

   接口 繼承 接口  單繼承  extends


   接口中沒有構造方法,接口中的所有屬性都是自帶 public static final

   接口中的所有方法自帶 public abstract


   抽象類和接口之間的區別:

      a.關鍵字不同,class  和  interface

      b.抽象類中有構造方法,接口中沒有構造方法

      c.抽象類支持單繼承,接口支持多繼承

      d.抽象類中的屬性可以是普通的,但接口中都是自帶public static final.

      e.抽象類中可以有普通方法,但是接口中都是自帶public abstract.

      f.抽象類中增加方法可以不對子類產生影響,但是接口中只要增加方法,就一定

        會影響子類


接口和抽象類的區別:

    1 關鍵字不同,接口是interface,抽象類是class。

    2 繼承方式不同,接口是多繼承,使用implemnets關鍵字;抽象類是單繼承,使用extends關鍵字。 

    3 接口中所有的屬性都是public的常量,抽象類的屬性可以隨便。

    4 接口中沒有構造方法的存在,抽象類一定有構造方法,但不能new,子類可以用super()調用。

    5 接口中的方法都是public abstract的,抽象類中可以有抽象方法,也可以有非抽象方法。

    6 接口有強制性,接口中的方法子類必須重寫,否則就是抽象類;抽象類未必。

    7 定義規範,最好使用接口而不是抽象類。


--------------------------------------------------------------------------------


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