天天看點

01 - JavaSE之基礎及面向對象JAVA基礎知識辨別符JAVA中的名稱規範常量與變量運算符成員變量引用構造方法方法重載(Overload)不同類型的記憶體分布this 指針static關鍵字package 和 importjava提供的包繼承和權限控制方法重寫(override/overwrite)super關鍵字繼承中的構造方法Object 類之 toString 方法Object類之 equals 方法對象轉型多态/動态綁定/遲綁定抽象類final 關鍵字interface 接口

JAVA基礎知識

  • Java 是SUN(Stanford University Network,斯坦福大學網絡公司)1995年推出的一門面向 Internet 的進階程式設計語言。
  • Java 虛拟機(JVM:Java Virtual Machine)
  • JRE(Java Runtime Environment):Java 運作環境

    (包括 JVM 和 Java 程式所需的核心類庫等,給使用者使用的)

    JDK(Java Development Kit)Java開發工具包(包括JRE,給Java開發人員使用的)

  • 使用 set 設定臨時環境變量

java set Path=xxx

  • 在寫簡單的 HelloWorld 程式的時候,可以使得 java 檔案名與類名不一緻,最後得到的位元組碼檔案的檔案名是和類名相同的;當包含 main 函數的類有 public 的時候,必須使得java檔案名和類名一緻,規定的。
  • 注意差別 set classpath=c:  與 set classpath=c:; 的差別(分号的有無),不加分号隻在目前目錄找,加了分号先到目前目錄找。是以以後不要加分号為好。
  • 注意 path 和 classpath 查找先後的差別:

    path是先到目前目錄查找,沒找到,再到path環境查找;

    classpath 是先到 classpath 環境查找,沒找到,再到目前目錄查找(前提加了分号)

  • 文檔說明書:對于文檔注釋,是java特有的注釋,其中注釋内容可以被JDK提供的工具 javadoc.exe 所解析,生成一套以網頁檔案形式展現的該程式的說明文檔

配置 JAVA 開發環境

JAVA_HOME = D:\jdk1.8.0_144
PATH = .;%PATH%;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;
CLASSPATH = .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar           

JAVA 環境安裝驗證

java -version
javac -version           

第一個 JAVA 程式

public class Demo
{
    public static void main(String[] args)
    {
        System.out.println("Hello Java!");
    }
}           

辨別符

  • 辨別符的組成:數字,字母,下劃線,美元符号
  • 開頭不能使用數字。
  • 可以使用中文作為變量名(編輯代碼的文本要為GBK格式,才能支援中文作為變量名)

JAVA中的名稱規範

  • 包名:多單詞組成時所有字母都小寫(xxxyyyzzz)
  • 類名接口名:多單詞組成時,所有的單詞的首字母大寫(XxxYyyZzz)
  • 變量名和函數名:多單詞組成時,第一個單詞首字母小寫,第二個單詞開始每個單詞首字母大寫(xxxYyyZzz)
  • 常量名:所有字母都大寫,多單詞時每個單詞用下劃線連接配接(XXX_YYY_ZZZ)

常量與變量

常量

  • JAVA中可以通過 final 關鍵字定義常量。例如:final int i = 0;

資料類型

  • 資料類型 = 基本資料類型 + 引用資料類型
  • 基本資料類型 = 整數型(byte,short,int,long) + 浮點型(float,double) + 字元型(char) + 布爾型(boolean)
  • 引用資料類型 = 類(class) + 接口(interface) + 數組([])

1、整數型

byte(-128 ~ 127)

short(-32768 ~ 32767)

int(-2147483648 ~ 2147483647)

Tips:

  • JAVA 中沒有無符号整數型變量
  • 隐式類型轉換(byte,short,char->int->long->float->double)
  • byte,short,char之間不會互相轉換,它們三者之間在計算時首先轉換成int類型,然後進行計算。
  • 容量大的資料類型轉換成容量小的資料類型時,要加強制轉換符,但是會造成精度降低或者溢出。
  • 有多種類型的資料混合運算時,系統首先自動将所有資料轉換成容量最大的那一種,然後再進行計算。

2、浮點型

  • JAVA 中 float 型浮點數加上字尾 f 或 F。
  • JAVA 中 double 型浮點數加上字尾 d 或 D。
  • JAVA 浮點數的預設類型是 double。
  • 将一個 float 類型的數,強制轉換成 long 類型,會舍去小數部分,而不是四舍五入。

3、邏輯型和字元型

  • JAVA中的邏輯型又叫布爾型,是一種隻能表示 true 和 false 兩種值的類型。
  • JAVA中的字元型占用兩個位元組,能夠表示 Unicode 字元(比如漢字)。
char c1 = 'c';
char c2 = '馮';           

4、引用資料類型

  • JAVA 中的引用資料類型類似 C 語言中的指針類型;
  • JAVA 中的引用資料類型主要用于類 class 定義的複雜資料類型(不是基本的資料類型,在代碼裡面是不會高亮顯示的,如String類型,是class定義的複雜資料類型。)
  • JAVA 中引用資料類型變量和常量的定義方式與基本資料類型相同。
  • 引用資料類型包括:類class,接口interface,數組。

運算符

1、算術運算符

  • ++和-- 優先級最高
  • 乘,/,% 優先級其次
  • +和- 優先級最低
  • 括号可以改變優先級

1、如果對負數取模,可以把模數的負号忽略,如 5%-2=1,但是被模數是負數就另當别論。

2、對于除号"/",它的整數除和小數除是由差別的:整數之間做除法時,隻保留整數部分而舍棄小數部分;小數之間做除法時(不論除數是小數還是被除數是小數)結果都是浮點類型。

3、"+"号除了字元串相加功能之外,還能把非字元串轉化為字元串。(System.out.println("5+5="+5+5); "+"運算符兩側的操作數隻要有一個是字元串String類型,系統會自動将另一個操作數轉換成字元串然後在進行連接配接。)

2、邏輯運算符

  • ! 運算優先級最高
  • && 運算優先級其次
  • || 運算優先級最低

3、關系運算符

  • JAVA 中同類型的變量和常量都可以使用 == 和 != 來判斷是否相等;
  • JAVA 中關系運算符的結果是個布爾值,而不是C語言中的1或0;
  • 關系運算符常和邏輯運算符一起使用。

4、位運算符

  • 位運算符是對整數進行二進制操作的運算符,傳回的結果也是一個整數;
  • 位運算符有按位取反~,按位與&,按位或|和按位異或^;
  • 移位運算符是左移<<,右移>>,無符号右移>>>.

5、條件運算符

  • Java中的條件運算符根據條件來傳回一個值
  • x = (布爾表達式) ? (為true時所賦的值) : (為false時所賦的值);
  • 例如:String s = (num < 2500)?("房貸沒壓力"):("房貸太高了");

1、if-else-

2、switch-case-

  • switch語句中的條件表達式隻能是int,short,byte,char
  • switch語句中的case後必須是常量且不能重複。

成員變量

成員變量(類的屬性)和局部變量的差別:

  • 成員變量:如果沒有初始化和指派的話,預設初始值為 0
  • 局部變量:沒有初始化的時候,通路的時候會報錯

引用

  • JAVA 語言中除了基本類型之外的變量類型都稱之為引用類型,如String類型。
當使用String s; 的時候,實際上有兩片記憶體,一片是一個索引叫s(棧),裡面裝的是一個位址;當 s = new String("JAVA"); 的時候,s才指向另一片空間(堆),這篇空間的内容為 "JAVA"。是以s并不是"JAVA",而是"JAVA"的引用。
一提到引用的概念,立馬想到一小塊記憶體(棧)指向一大塊記憶體(堆)。

構造方法

  • 使用new + 構造方法 建立一個新對象
  • 當沒有指定構造函數時,編譯器為類自動添加預設構造函數。
  • 構造方法是在 JAVA 類中的一個用來初始化對象的函數
  • 構造方法與類同名且沒有傳回值
第三章記憶體解析6-11課實在是太精彩了,不多說,自己看!!!

方法重載(Overload)

  • 方法名相同 + 參數不同:參數個數不同/參數類型不同
  • 傳回值類型不同(不構成重載)

與普通方法一樣,構造方法也可以重載

不同類型的記憶體分布

  • 當建立該類對象的時候,靜态變量、靜态方法就會被放到記憶體裡了,就算沒有new一個對象,static靜态變量依然存在于 data segment 區域。
  • 記憶體分為四個區:stack segment,heap segment,data segment,code segment;

    stack 區存放函數參數和局部變量;

    heap 區存放對象(包括成員變量:成員變量在堆記憶體配置設定,因為成員變量隻有在new出來的時候才會配置設定空間,是以配置設定在堆記憶體;而局部變量配置設定在棧記憶體。);

    data 區存放static 的變量或者字元串常量;

    code 區存放類中的方法;

this 指針

  • 在類的方法定義中使用的this關鍵字代表使用該方法的對象的引用。
  • 哪個對象調用該方法的this,this就指向哪個對象。
  • this可以看成一個成員變量,它的值是目前對象的引用。

static關鍵字

  • 在類中,用static聲明的成員變量為靜态成員變量,它為該類的功用變量,在第一次使用(第一次new一個對象的時候)的時候被初始化,對于該類的所有對象來說,static成員變量隻有一份。
  • 用static聲明的方法為靜态方法,在調用該方法的時候,不會将對象的引用傳遞給它,是以在static方法中不可以方位非static的成員。
  • static成員變量配置設定在資料區,是以記憶體的布局,除了 stack 和 heap 之外又多了一塊 Data Segment 區域。
  • 靜态成員變量可以使用 “類名.靜态成員變量” 來通路,當然也可以使用 “對象.靜态成員變量” 來通路。
  • 靜态成員函數不能調用非靜态成員成員變量和非靜态成員函數,因為靜态的成員函數不需要new一個對象出來(使用static聲明的方法為靜态方法,在調用該方法的時候,不會将對象的引用傳遞給它,是以在static方法中不可通路非static成員),既然沒有對象,那麼其内的非靜态成員變量和非靜态成員函數就無法執行,是以靜态成員函數不能調用非靜态成員成員變量和非靜态成員函數。
  • 靜态與非靜态的成員變量都可以在定義的時候指派,隻不過意義不同。

package 和 import

  • 為了便于管理大型軟體系統中數目衆多的類,解決類的命名沖突的問題,java引入包(package)機制,提供類的多重類命名空間。相當于對相同名字的不同類加上了一個獨一無二的路徑。
  • package 語句作為 java 源檔案的第一條語句,指明該檔案中定義的類所在的包。(若預設包語句,則為無名包)
  • 給包取名,約定俗成的是公司的域名倒過來:例如公司為www.google.com,那麼給你的類打包時取名可以是:package com.google.javatest;等。
  • java編譯器把包對應于檔案系統的目錄管理,package語句中,用"."來指明包目錄的層次,如上package com.google.javatest,表示該檔案中所在的類位于 "./com/google/javatest"目錄下。如果其他的類調用了該檔案中的類,那麼該檔案的類對應的class檔案就需要位于"./com/google/javatest" 目錄下。
  • 假如該檔案中的一個類叫Cat類,那麼在其他類使用的時候,比如new一個Cat對象,那麼就要這麼寫:

java com.google.javatest.Cat cat = new com.google.javatest.Cat();

**需要把Cat類的路徑加上,否則找不到這個Cat類(如果将一個類打包,則使用該類時,必須使用該類的全名,java編譯器才能找到該類)。這樣就太麻煩了,解決辦法就是使用import。使用import在檔案的開頭引入要使用的類,例如 import com.google.javatest.Cat;import com.google.javatest.*;**

  • 可以不需要使用 import 語句直接使用java.lang包中的類,比如String類。
  • 注意打包的源檔案可能對編譯産生影響,可以将打完包(生成了對應的class檔案)的源檔案(java源檔案)删除或者轉移目錄。
  • 注意:如果按照以上import com.google.javatest.Cat;的寫法,那麼我們調用Cat類的 java 源檔案的路徑要和com路徑位于同一層目錄,否則又會找不到路徑。(必須class檔案的最上層的包的父目錄位于classpath下。比如上面的class檔案最上層的包是com目錄,com目錄的父目錄是目前目錄,就是"."目錄,是位于classpath目錄下的。)

java提供的包

怎麼看java提供的包有哪些呢?位于D:\Java\jdk\jre\lib\rt.jar裡面,解壓出就可以看到。

主要包介紹:

  • java.lang 包含一些java語言的核心類,如String,Math,Integer,System和Thread,提供常用功能。
  • java.awt 包含了構成抽象視窗工具集的多個類,這些類被用來建構和管理應用程式的圖形使用者界面(GUI)。
  • java.applet 包含applet運作所需的一些類。
  • java.net 包含執行與網絡相關的操作的類。
  • java.io 包含能提供多種輸入輸出功能的類。
  • Java.util 包含一些實用工具類,如sing一系統特性,實用與日期月曆相關的函數。

PS:可以不需要使用import語句直接使用java.lang包。

怎麼打包我們自己的包為jar檔案呢?執行:jar -cvf xxx.jar path(path表示你需要打包的包的路徑)

可以把jar封包件當成路徑設定到classpath變量,這樣我們就可以使用jar包。效果和真實的路徑相同。

繼承和權限控制

修飾符 類内部 同一個包 子類(可以不同的包) 不同包的非子類
private yes
default
protected
public
  • 類的可見性
  1. java 語言規定一個檔案隻能有一個類被聲明為 public
  2. public的類必須與檔案名完全相同。
  3. public類可以被其他包中的類導入使用,default類隻能被同一個包内部的類通路
  4. protected 和 private 不能用于限定類的可見性,對類的修飾權限隻能使用public和default
  • 類的繼承
  1. java中使用 extends 關鍵字實作類的繼承機制。
  2. java隻支援單繼承,不允許多繼承。
  • 一些建議
  1. 每個屬性和方法都顯式聲明通路權限,不使用預設權限。
  2. 對于邏輯上對外不可見的屬性和方法盡量設定為private。
  3. 雖然java語言中同一個包中的其他非子類可以自由通路protected成員,但這是不推薦的。
  4. 将邏輯上相關的類組織在一個包中,以包的形式組織程式的類。

方法重寫(override/overwrite)

  • 在子類中可以根據需要對從基類中繼承來的方法進行重寫。
  • 重寫方法必須與被重寫方法具有相同的方法名稱,參數清單,傳回值。(就是方法一模一樣才行)
  • 重寫方法不能使用比被重寫方法更嚴格的通路權限。

super關鍵字

  • 在java中使用 super 來引用基類的成員。
  • 當子類和父類有同名成員變量的時候,子類成員變量不會覆寫父類成員變量,子類成員變量重寫父類的成員變量,使得父類成員變量被隐藏,使用super 可以通路父類成員變量。

-當一個子類繼承父類時,相當于子類自動多了兩個成員變量,一個是this,指向子類對象,一個是super指向子類對象中的父類對象。

繼承中的構造方法

  • 子類的構造過程中必須調用其基類的構造方法(先父母,後客人,最後自己)
  • 子類可以在自己的構造方法中使用 super 調用基類的構造方法(使用 this調用本類的另外構造方法)
  • 如果子類的構造方法沒有顯式調用基類的構造方法,則系統預設調用基類的無參數的構造方法。
  • 如果子類構造方法中既沒有顯式調用基類構造方法,而基類中又沒有無參數的構造方法,則編譯出錯。

Object 類之 toString 方法

  • Object類是所有 java 類的根基類。
  • 如果在類的聲明中未使用 extends 關鍵字指明其基類,則預設基類為Object 類。
  • Object 類的 toString 方法,建議所有子類覆寫此方法(It is recommended that all subclasses override this method.)

Object類之 equals 方法

  • Object 類中定義 public boolean equals(Object obj) 方法,提供對象是否相等的邏輯。
  • Object 的 equals 方法定義為:x.equals(y)當x和y是同一個對象的引用時傳回 true,否則傳回 false。
  • java SDK 提供的一些類,如String,Date等,重寫了Object的 equals 方法,調用這些類的 equals 方法,x.equals(y)當x 和y 所引用的對象是同一類對象且屬性相同時(并不一定是相同對象),傳回 true,否則傳回false。
  • 可以根據需要重寫equals方法。

對象轉型

  • 一個基類的引用類型變量可以指向其子類的對象。
  • 一個基類的引用不可以通路其子類對象新增加的成員(屬性和方法)。
  • 可以使用(引用變量 instanceof 類名)來判斷該引用型變量所指向的對象是否屬于該類或該類的子類。
  • 子類的對象可以當做基類的對象來使用稱作向上轉型,反之成為向下轉型。

多态/動态綁定/遲綁定

  • 動态綁定是指在執行期間(而非編譯期間)判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
  • 條件:
  1. 要有繼承
  2. 子類重寫父類方法
  3. 父類引用指向子類對象
  • 當父類引用指向子類對象的時候,父類對象不能通路子類新增的成員變量和成員方法。

抽象類

  • 用 abstract 關鍵字來修飾一個類時,這個類叫做抽象類;用 abstract 來修飾一個方法時,該方法叫做抽象方法。
  • 含有抽象方法的類必須被聲明為抽象類,抽象類必須被繼承,抽象方法必須被重寫。
  • 抽象類不能被執行個體化。
  • 抽象方法隻需聲明,而不需要實作。

final 關鍵字

  • final 的變量(成員變量,局部變量)的值不能被改變。
  • final 的方法不能被重寫。
  • final 的類不能被繼承。

interface 接口

  • 接口是抽象方法和常量值的定義的集合。
  • 從本質上講,接口是一種特殊的抽象類,這種抽象類隻包含常量(static final類型的成員變量)和方法的定義,而沒有變量和方法的實作。
  • 接口實作方式:
interface Singer {
    public void sing();
    public void sleep();
}

class Student implements Singer { // 學生不是繼承(extends)Singer,而是實作(implements)Singer
    
}           
  • 多個無關的類可以實作(implements 類似繼承)同一個接口。
interface Singer {
    public void sing();
    public void sleep();
}

class Student implements Singer {
    // ...
}

class Dog implements Singer {
    // ...
}           
  • 一個類可以實作(implements 類似繼承)多個無關的接口。
class Teacher implements Singer, Painter {
}           
  • 與繼承關系類似,接口與實作類之間存在多态性。

接口特性

  • 接口可以多重實作。
  • 接口中的成員變量預設為 public static final 的;也隻能是 public static final 的。
  • 接口中隻能定義抽象方法,而且這些成員方法預設為public的,也隻能是public的。
  • 接口可以繼承其他的接口,并添加新的屬性和抽象方法。
如果兩個接口有相同的方法,但是有個類同時實作了這兩個接口會怎樣呢?
  • 隻需要實作一次就好了。*
如果兩個接口有名稱相同的方法,隻是傳回值不一樣,但是有個類同時實作了這兩個接口會怎樣呢?
  • 你說同時實作這兩個方法就好了,但是這兩個方法并不構成重載,無法區分這兩個方法的,是以目前無解,記住不要這樣實作。哈哈,以後查到了再說。*
  • 子類重寫父類的方法時,方法的通路權限必須等于或大于父類的方法通路權限,也就是說實作接口的方法的權限必須為public,因為接口的方法為public。

    否則編譯的錯誤為:

    ```java

  • Test.java:44: 錯誤: Worker中的playWithPet()無法實作PetCarer中的playWithPet()

    void playWithPet() {

    ^

    正在嘗試配置設定更低的通路權限; 以前為public *

    ```