java基礎(chǔ)篇——面向?qū)ο?/font>

作者:xcbeyond
瘋狂源自夢想,技術(shù)成就輝煌!微信公眾號:《程序猿技術(shù)大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗,樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項目的研發(fā)工作,涉及架構(gòu)設(shè)計、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗。

引言:

        面向?qū)ο蟮乃枷胝荍ava學(xué)習(xí)的核心部分,要是沒有搞懂面向?qū)ο?,那么就稱不上學(xué)過Java,因此,搞懂面向?qū)ο笫侵陵P(guān)重要的。對于初學(xué)者而言,首次接觸面向?qū)ο髸r,總感覺怪怪的,不知道究竟在干什么(我剛開始接觸也是這種感覺,漸漸的就找到感覺了),這其實都是正?,F(xiàn)象的,不然怎么有人說他是很抽象的啊。面向?qū)ο?,簡單的理解就是把一切事物按照它自己本有存在的特征、屬性通過自然組織語言組織起來,然后再用編程語言來實現(xiàn)。例如:人(類)本該就分有性別(男、女)、年齡、姓名等屬性特征,然對于每一個而言,他們往往具體不同的這些屬性特征值,于是就從“人”(類)這個類別中具體出來了每個人,即:類的實例化得到了對象。就可以對象他們進行相應(yīng)的操作了。

面向?qū)ο?OO):

         按照東西的特征和自然組織形式, 進行軟件開發(fā)過程的組織, 是一個開發(fā)過程的方法論。

 

學(xué)習(xí)面向?qū)ο?

      - 學(xué)習(xí)如何用OO語法描述事物的特征和自然組織形式.

      - 學(xué)習(xí)面向?qū)ο笏季S的前提是樸素的哲學(xué)邏輯.

            如: 多態(tài), 抽象概念的具體實現(xiàn)是多態(tài)的,

             如:美女是多態(tài)的!

 

一、類(Class):

       它是一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu),是把一類相似或相關(guān)聯(lián)數(shù)據(jù)的相關(guān)操作封裝在一起的一個集合。

  1、類是用來描述一個領(lǐng)域模型中的具體概念(名詞)的。

  2、領(lǐng)域模型: 一個應(yīng)用軟件業(yè)務(wù)范疇, 也叫業(yè)務(wù)模型.

  3、屬性: 描述具體概念(事物)的特征.

    如:<圖書館管理系統(tǒng)>中的概念: 書 Book

        書的特征: 書號, 書名, 編號, 作者, 價格...

 

Java中類的寫法(語法)如下:

 修飾詞 class 類名{

   修飾詞 類型 屬性;

  修飾符 返回值類型  方法名 {

      //  方法體(實現(xiàn)類的相關(guān)操作)

      }

  }

如:

     public class Book{
          int id;
          String name;
          String[] authors;
          String isbn;
          double price;
      }


 

二、對象:

  1、      對象是類的具體實例!

           比 如,書Book這個類,它只是代表了一類,你卻不知道它到底是什么書,但你只知道它擁有哪些特點屬性,即書名、書號、作者、書價等(類屬性)信息,為了對書Book這個類具體化,就引出了“對象”的概念,因此,對象就是類的具體實例。如:《山楂樹之戀》是一本書,《和空姐同居的日子》是一本書,他們屬于Book類的兩個不同的對象。

          對象的創(chuàng)建是通過“new”運算符進行實例化的,即:

                      

              Book book = new Book();//book:引用 new Book():對象

        看到這里,你或許還是一頭霧水,請不必?fù)?dān)心,先暫時記住就行了,隨后你就會徹底明白了。new Book()它是真正的在內(nèi)存中(準(zhǔn)確的說是在“堆”內(nèi)存中)創(chuàng)建了一個Book類的對象,此時在“棧”中創(chuàng)建了一個Book類型(類也屬于一種數(shù)據(jù)類型,一種引用類型中的“類類型”)的引用變量book,最終將變量book的地址指向了new Book()創(chuàng)建的對象。<這里地址指向關(guān)系,是隱含存在的一種指針,可以這么理解,僅供理解而已。但java卻是不存在指針的哦!>   。關(guān)于“堆”、“棧”可以參考《java核心內(nèi)容——分配管理》了解。

     引用:是指向具體對象的句柄,相當(dāng)于自然語言的代詞。   

       1> 代詞本身不是對象,代詞引用了一個具體對象。

        2> 在特殊情況下引用(代詞)可能指空。

        3> 經(jīng)常簡單的敘述事物時候,不嚴(yán)格區(qū)別引用與對象。

       如:  

       Book book = new Book();//book:引用   new Book():對象  
     
        book.name = "月子";
     
       book.authors = new String[]{"白云","黑土"};
     
       book = null;//book引用null  
     
     

      4>引用是null時候,訪問屬性或方法時候會出現(xiàn): 空指針異常

     如:

    book = null;
     
    System.out.println(book.name);//異常   
     

2、構(gòu)造器(構(gòu)造方法):

       在上面語句Book   book  =   new  Book()中,或許對用new  Book()創(chuàng)建對象時,并不知道其真正的含義,其中Book()就是一個Book類的一個構(gòu)造器(特殊的方法),用它來對對象的屬性進行初始化。

構(gòu)造器的使用:

 1>、聲明在類內(nèi)部, 方法名與類名一致的方法叫構(gòu)造方法, 構(gòu)造方法不能聲明返回值類型。

 2>、構(gòu)造方法可以包含參數(shù), 參數(shù)一般是創(chuàng)建對象實例,必須依賴的條件(前提條件)。

如:

    public Book(int id,String name,String isbn) {
     
    this.id = id;
     
    this.name = name;
     
    this.isbn = isbn;
     
    }
     

  3>、構(gòu)造方法經(jīng)常會重載

        方法重載:方法的重新書寫,即重載

               - 方法名一樣

              - 方法參數(shù)不一樣

 

默認(rèn)構(gòu)造器:

            對于每一個類都會存在一個構(gòu)造器的,只是有些是使用的默認(rèn)構(gòu)造器而已,沒有顯式的顯示出來。

  1>、如果類沒有聲明任何構(gòu)造器,Javac自動提供一個默認(rèn)構(gòu)造器, 無參數(shù)默認(rèn)構(gòu)造器。

  2>、如果提供構(gòu)造器聲明, Javac將不再提供默認(rèn)構(gòu) 造器。

如:(這個程序只是為了說明默認(rèn)構(gòu)造器而已,沒有其他實際價值)

    /**
     * 默認(rèn)構(gòu)造器的演示
     * @author xcbeyond
     *
     */
    public class ConstructorDemo {
        public static void main(String[] args) {
            Foo foo = new Foo();
            //Goo goo = new Goo();//錯誤,沒有參數(shù)的構(gòu)造器
            //System.out.println(foo.a+","+goo.a);
            //A 、編譯錯誤         B、 1,0   C、 1,1  D、
        }
    }
    class Foo {//沒有顯式的顯示構(gòu)造器,即使用默認(rèn)構(gòu)造器(無參構(gòu)造器)
        int a = 1;
    }
    class Goo{//沒有無參構(gòu)造器了
        int a ;
        public Goo(int a) {//默認(rèn)無參構(gòu)造器被重載成為了一個有參構(gòu)造器
            this.a = a;
        }
    }

 

new運算: 創(chuàng)建對象實例,如: Book book = new Book();

  1、根據(jù)類的屬性在堆中分配對象空間。






  2、根據(jù)參數(shù)類型調(diào)用構(gòu)造器。

  3、new運算返回對象的引用地址。

 

對象的創(chuàng)建過程:

  1、根據(jù)類的屬性在堆中分配對象空間,并且自動初始化。

  2、根據(jù)參數(shù)類型調(diào)用構(gòu)造器。

 

this:

  最大的作用就是讓類中一個方法訪問該類的另一個方法或?qū)傩浴his可以代表任何對象。

   - this 是對當(dāng)前對象的引用, 是當(dāng)前對象本身。

   - 可以使用this明確的訪問當(dāng)前對象的屬性或者方法。

   - this() 是調(diào)用本類的其他構(gòu)造器, 可以使用構(gòu)造器的重用, 簡化代碼的實現(xiàn).

   - this() 必須寫在構(gòu)造器的第一行!

    如:public Book(int id ,String name) {
                //System.out.print(id);//錯 ,this()必須寫在第一行
            this(id,name,null);
        }
        public Book(int id,String name,String isbn) {
            this.id = id;
            this.name = name;
            this.isbn = isbn;
        }


 

java方法參數(shù)的傳遞規(guī)則:

             參數(shù)傳遞方式只有一種:值傳遞。值傳遞就是將實際參數(shù)值得副本(復(fù)制品)傳入方法內(nèi),而參數(shù)本身不會受到任何影響。

 1、基本類型就是其中值的復(fù)制, 引用類型是引用值(地址)的復(fù)制。

 2、 變量的值:

    - 基本類型的值是其本身

    - 引用變量的值是一個地址值,是被引用對象的首地址

 3、為了避免引用參數(shù)傳遞的副作用, 建議一切結(jié)果使用返回值帶回。

如:

    /**
     * Java方法參數(shù)傳遞規(guī)則:基于值的傳遞,是變量值的復(fù)制
     *     為了避免引用方法參數(shù)傳遞的副作用,建議一切結(jié)果使用返回值返回
     * @author xcbeyond
     */
    public class ParamaterDemo {
        public static void main(String[] args) {
            Koo koo = new Koo();
            int a = 1;
            update(a);
            update(koo);
            System.out.println("a="+a+",koo.a="+koo.a);//a=1,koo.a=2
            
            int b = update2(a);
            int c = update2(koo);
            System.out.println("b="+b+",c="+c);//2,3
            
        }
        
        public static void update(int a ) {
            a++;
        }
        public static void update(Koo koo) {
            koo.a++;
        }
        
        public static int  update2(int a ) {
            a++;
            return a;
        }
        public static int update2(Koo koo) {
            koo.a++;
            return koo.a;
        }
    }
     
    class Koo {
        int a = 1;
    }

 

3、繼承:

    考慮到程序的實時擴展(添加新的屬性、方法等操作),更好的進行維護,于是引入“繼承”這個概念。它是在原有類的基礎(chǔ)上添加或修改(重寫)新的屬性和方法。子類繼承了父類的所有方法和屬性。

    用來表達類型概念上具體化,Java繼承用extends 關(guān)鍵字。子類是父類的具體化,父類是子類的泛化(概念抽象化)

 1>、子類繼承父類的屬性和方法

 2>、構(gòu)造器不能繼承!

 3>、實例化子類,會遞歸分配所有父類的空間

 4>、子類默認(rèn)調(diào)用父類的無參數(shù)構(gòu)造器

繼承特點:

  1>、子類繼承父類的屬性和方法

  2>、構(gòu)造器不能繼承

  3>、創(chuàng)建子類實例,會遞歸分配所有父類的空間

  4>、子類默認(rèn)調(diào)用父類的無參數(shù)構(gòu)造器

  5>、子類可以覆蓋(重寫)父類的方法,修改父類行為

  6>、JAVA只能單一繼承

繼承中的語法現(xiàn)象:

  1>, 父類可以引用子類的實例,父類的實現(xiàn)是多態(tài)的。

  2>, 子類可以覆蓋父類的方法,修改父類的行為。

     - 方法覆蓋:子類覆蓋了父類“相同方法簽名”的方法。

     - 方法的覆蓋是由方法動態(tài)綁定實現(xiàn)的,就是java虛擬機運行時候確定執(zhí)行那個方法,java最終執(zhí)行子類的方法。

關(guān)于繼承中的構(gòu)造器:

  1> 、子類遞歸調(diào)用父類構(gòu)造器。

  2> 、默認(rèn)調(diào)用父類無參數(shù)構(gòu)造器!

  3> 、如果父類沒有無參數(shù)構(gòu)造器,就必須在子類中明確指定調(diào)用父類的有參數(shù)構(gòu)造器!

  4> 、使用super()調(diào)用父類構(gòu)造器,必須寫在子類構(gòu)造器第一行。

  5> 、編程建議:所有的類都提供無參數(shù)構(gòu)造器!減少繼承時候的麻煩。


如:

 

    /**
     * 子類構(gòu)造器一定調(diào)用父類的構(gòu)造器!
     * @author xcbeyond
     *
     */
     
    public class ConstructorDemo {
        public static void main(String[] args) {
            Goo goo = new Goo();
            System.out.println(goo.a);//5
        }
    }
     
    class Foo extends Object {//任何類都繼承Object類(超類)
        int a = 1;
     
        public Foo(int a) {
            super();//Object類的構(gòu)造器
            this.a = a;
        }
        
        public void Foo() {//構(gòu)造方法沒有返回類型值,這里并不是構(gòu)造方法,而是一個一般的方法而已!
            
        }
    }
     
    //class Goo extends Foo{}  //錯 , 父類沒有無參數(shù)構(gòu)造器
    class Goo extends Foo{
        public Goo() {
            //System.out.println();//super()必須放在構(gòu)造器的第一行
            super(5);//明確調(diào)用父類由參數(shù)構(gòu)造器
        }
    }

 

對象的實例化過程

  1>、 檢查類是否加載,如果沒有加載就加載這個類

    - 如果有父類,要加載所有父類

    - 懶惰式加載,如果第一次用到就加載,只加載一次

    - 通過CLASSPATH指定的路徑尋找類文件

    - 加載以后是一個對象,類型是Class

  2>、在內(nèi)存堆中分配對象空間

      遞歸分配所以父類屬性空間,然后分別子類的空間,屬性默認(rèn)自動初始化,自動初始化為“0”值:null,0,false,\u0000

  3>、執(zhí)行屬性的賦值

  4>、遞歸調(diào)用父類構(gòu)造器。(默認(rèn)調(diào)用父類無參數(shù)構(gòu)造器!)

  5>、調(diào)用本類構(gòu)造器

 

訪問控制:

   訪問控制修飾詞:public  protected  default  private

    - 聲明屬性和方法盡可能私有,這樣才能做到盡可能封裝

    - 提供適當(dāng)?shù)膶傩栽L問方法,適當(dāng)?shù)拈_放屬性的訪問

    - 不建議使用非公有類。就是說所有類都應(yīng)該是公有的,并且一個源文件一個類

 

屬性是靜態(tài)綁定到變量類型。

    方法是動態(tài)綁定,由最終對象的方法決定。

如:

    /**
     * 屬性是靜態(tài)綁定到變量類型
     * 方法是動態(tài)綁定,有最終對象的方法決定
     * @author xcbeyond
     *
     */
    public class FiledAccessDemo {
        public static void main(String[] args) {
            Goo goo = new Goo();
            Foo foo = goo;
            
            System.out.println(goo.a+","+goo.getA());//2,2
            System.out.println(foo.a+","+foo.getA());//1,2
        }
     
    }
    class Foo {
        int a = 1;
        public int getA() {
            return a;
        }
    }
    class Goo extends Foo {
        int a = 2;
        public int getA() {
            return a;     //retrun super.a;
        }
    }