1. 程式人生 > >菜鳥教程 Java 學習筆記 (基礎教程)

菜鳥教程 Java 學習筆記 (基礎教程)

1、Java 物件和類

Java作為一種面向物件的語言,支援以下基本概念:多型、繼承、封裝、抽象、類、物件
例項、方法、過載。

物件:物件是類的一個例項,有狀態和行為。
類:類是一個模板,它描述一類物件的行為和狀態。

1.1 建立物件

物件是根據類建立的,在Java中,使用關鍵字new來建立一個新的物件。建立物件需要以下三步:
(1) 宣告:宣告一個物件,包括物件名稱和物件型別。
(2) 例項化:使用關鍵字new來建立一個物件。
(3) 初始化:使用new建立物件時,會呼叫構造方法初始化物件。

1.2 構造方法

每個類都有構造方法。如果沒有顯式地為類定義構造方法,Java編譯器將會為該類提供一個預設構造方法。
在建立一個物件的時候,至少要呼叫一個構造方法。構造方法的名稱必須與類同名,一個類可以有多個構造方法。
下面是一個構造方法示例:

public class Puppy{
   public Puppy(String name){
      //這個構造器僅有一個引數:name
      System.out.println("小狗的名字是 : " + name ); 
   }
   public static void main(String []args){
      // 下面的語句將建立一個Puppy物件
      Puppy myPuppy = new Puppy( "tommy" );
   }
}

1.3 Java包

包主要用來對類和介面進行分類。當開發Java程式時,可能編寫成百上千的類,因此很有必要對類和介面進行分類。

1.4 Import語句

在Java中,如果給出一個完整的限定名,包括包名、類名,那麼Java編譯器就可以很容易地定位到原始碼或者類。Import語句就是用來提供一個合理的路徑,使得編譯器可以找到某個類。
例如,下面的命令列將會命令編譯器載入java_installation/java/io路徑下的所有類

import java.io.*;

一個簡單的例子

在該例子中,我們建立兩個類:Employee 和 EmployeeTest。
首先開啟文字編輯器,把下面的程式碼貼上進去。注意將檔案儲存為 Employee.java。
Employee類有四個成員變數:name、age、designation和salary。該類顯式聲明瞭一個構造方法,該方法只有一個引數。

Employee.java 檔案程式碼:

import java.io.*;

public class Employee{
   String name;
   int age;
   String designation;
   double salary;
   // Employee 類的構造器
   public Employee(String name){
      this.name = name;
   }
   // 設定age的值
   public void empAge(int empAge){
      age =  empAge;
   }
   /* 設定designation的值*/
   public void empDesignation(String empDesig){
      designation = empDesig;
   }
   /* 設定salary的值*/
   public void empSalary(double empSalary){
      salary = empSalary;
   }
   /* 列印資訊 */
   public void printEmployee(){
      System.out.println("名字:"+ name );
      System.out.println("年齡:" + age );
      System.out.println("職位:" + designation );
      System.out.println("薪水:" + salary);
   }
}

程式都是從main方法開始執行。為了能執行這個程式,必須包含main方法並且建立一個例項物件。
下面給出EmployeeTest類,該類例項化2個 Employee 類的例項,並呼叫方法設定變數的值。
將下面的程式碼儲存在 EmployeeTest.jav a檔案中。

EmployeeTest.java 檔案程式碼:

import java.io.*;
public class EmployeeTest{

   public static void main(String args[]){
      /* 使用構造器建立兩個物件 */
      Employee empOne = new Employee("RUNOOB1");
      Employee empTwo = new Employee("RUNOOB2");

      // 呼叫這兩個物件的成員方法
      empOne.empAge(26);
      empOne.empDesignation("高階程式設計師");
      empOne.empSalary(1000);
      empOne.printEmployee();

      empTwo.empAge(21);
      empTwo.empDesignation("菜鳥程式設計師");
      empTwo.empSalary(500);
      empTwo.printEmployee();
   }
}

編譯這兩個檔案並且執行 EmployeeTest 類,可以看到如下結果:

$ javac EmployeeTest.java
$ java EmployeeTest 
名字:RUNOOB1
年齡:26
職位:高階程式設計師
薪水:1000.0
名字:RUNOOB2
年齡:21
職位:菜鳥程式設計師
薪水:500.0

2、Java 基本資料型別

2.1 Java語言提供了八種基本型別

1、byte

byte資料型別是8位、有符號的,以二進位制補碼錶示的整數;
最小值是-128(-2^7);
最大值是1272^7-1);
預設值是0byte型別用在大型陣列中節約空間,主要代替整數,因為byte變數佔用的空間只有int型別的四分之一;
例子:byte a = 100byte b = -50

2、short

short資料型別是16位、有符號的以二進位制補碼錶示的整數
最小值是-32768(-2^15);
最大值是327672^15 - 1);
Short資料型別也可以像byte那樣節省空間。一個short變數是int型變數所佔空間的二分之一;
預設值是0;
例子:short s = 1000short r = -20000

3、int

int資料型別是32位、有符號的以二進位制補碼錶示的整數;
最小值是-2,147,483,648(-2^31);
最大值是2,147,483,6472^31 - 1);
一般地整型變數預設為int型別;
預設值是0;
例子:int a = 100000, int b = -200000

4、long

long資料型別是64位、有符號的以二進位制補碼錶示的整數;
最小值是-9,223,372,036,854,775,808(-2^63);
最大值是9,223,372,036,854,775,8072^63 -1);
這種型別主要使用在需要比較大整數的系統上;
預設值是0L;
例子: long a = 100000L,Long b = -200000L

5、float

float資料型別是單精度、32位、符合IEEE 754標準的浮點數;
float在儲存大型浮點陣列的時候可節省記憶體空間;
預設值是0.0f;
浮點數不能用來表示精確的值,如貨幣;
例子:float f1 = 234.5f

6、double

double資料型別是雙精度、64位、符合IEEE 754標準的浮點數;
浮點數的預設型別為double型別;
double型別同樣不能表示精確的值,如貨幣;
預設值是0.0d;
例子:double d1 = 123.4

7、boolean

boolean資料型別表示一位的資訊;
只有兩個取值:truefalse;
這種型別只作為一種標誌來記錄true/false情況;
預設值是false;
例子:boolean one = true

8、char

char型別是一個單一的16Unicode字元;
最小值是’\u0000’(即為0);
最大值是’\uffff’(即為65,535);
char資料型別可以儲存任何字元;
例子:char letter = ‘A’。

2.2 Java常量

常量在程式執行時,不會被修改的量。
在 Java 中使用 final 關鍵字來修飾常量,宣告方式和變數類似:

final double PI = 3.1415927;

3. Java變數型別

Java語言支援的變數型別有:區域性變數、成員變數、類變數。

3.1 區域性變數

1、區域性變數宣告在方法、構造方法或者語句塊中;
2、區域性變數在方法、構造方法、或者語句塊被執行的時候建立,當它們執行完成後,變數3、將會被銷燬;
4、訪問修飾符不能用於區域性變數;
5、區域性變數只在宣告它的方法、構造方法或者語句塊中可見;
6、區域性變數是在棧上分配的。
7、區域性變數沒有預設值,所以區域性變數被聲明後,必須經過初始化,才可以使用。

3.2 例項變數

1、例項變數宣告在一個類中,但在方法、構造方法和語句塊之外;
2、當一個物件被例項化之後,每個例項變數的值就跟著確定;
3、例項變數在物件建立的時候建立,在物件被銷燬的時候銷燬;
4、例項變數的值應該至少被一個方法、構造方法或者語句塊引用,使得外部能夠通過這些5、方式獲取例項變數資訊;
6、例項變數可以宣告在使用前或者使用後;
7、訪問修飾符可以修飾例項變數;
8、例項變數對於類中的方法、構造方法或者語句塊是可見的。一般情況下應該把例項變數9、設為私有。通過使用訪問修飾符可以使例項變數對子類可見;
10、例項變數具有預設值。數值型變數的預設值是0,布林型變數的預設值是false,引用型別變數的預設值是null。變數的值可以在宣告時指定,也可以在構造方法中指定;
11、例項變數可以直接通過變數名訪問。但在靜態方法以及其他類中,就應該使用完全限定名:ObejectReference.VariableName。

3.2 類變數 (靜態變數)

1、類變數也稱為靜態變數,在類中以static關鍵字宣告,但必須在方法構造方法和語句塊之外。
2、無論一個類建立了多少個物件,類只擁有類變數的一份拷貝。
3、靜態變數除了被宣告為常量外很少使用。常量是指宣告為public/private,final和static型別的變數。常量初始化後不可改變。
4、靜態變數儲存在靜態儲存區。經常被宣告為常量,很少單獨使用static宣告變數。
5、靜態變數在程式開始時建立,在程式結束時銷燬。
6、與例項變數具有相似的可見性。但為了對類的使用者可見,大多數靜態變數宣告為public型別。
7、預設值和例項變數相似。數值型變數預設值是0,布林型預設值是false,引用型別預設值是null。變數的值可以在宣告的時候指定,也可以在構造方法中指定。此外,靜態變數還可以在靜態語句塊中初始化。
8、靜態變數可以通過:ClassName.VariableName的方式訪問。
9、類變數被宣告為public static final型別時,類變數名稱一般建議使用大寫字母。如果靜態變數不是public和final型別,其命名方式與例項變數以及區域性變數的命名方式一致。

4. Java 修飾符

Java語言提供了很多修飾符,主要分為以下兩類:訪問修飾符、非訪問修飾符;

4.1 訪問控制修飾符

Java中,可以使用訪問控制符來保護對類、變數、方法和構造方法的訪問。Java支援4種不同的訪問許可權。
1、預設的,也稱為 default,在同一包內可見,不使用任何修飾符。
2、私有的,以 private 修飾符指定,在同一類內可見。
3、共有的,以 public 修飾符指定,對所有類可見。
4、受保護的,以 protected 修飾符指定,對同一包內的類和所有子類可見。

4.2 非訪問控制修飾符

為了實現一些其他的功能,Java 也提供了許多非訪問修飾符。

4.2.1 static 修飾符,用來建立類方法和類變數。

靜態變數:
static 關鍵字用來宣告獨立於物件的靜態變數,無論一個類例項化多少物件,它的靜態變數只有一份拷貝。 靜態變數也被成為類變數。區域性變數不能被宣告為 static 變數。

靜態方法:
static 關鍵字用來宣告獨立於物件的靜態方法。靜態方法不能使用類的非靜態變數。靜態方法從引數列表得到資料,然後計算這些資料。

對類變數和方法的訪問可以直接使用 classname.variablename 和 classname.methodname 的方式訪問。
如下例所示,static修飾符用來建立類方法和類變數。

4.2.2 final 修飾符,用來修飾類、方法和變數

final 修飾的類不能夠被繼承,修飾的方法不能被繼承類重新定義,修飾的變數為常量,是不可修改的。

final 變數
final 變數能被顯式地初始化並且只能初始化一次。被宣告為 final 的物件的引用不能指向不同的物件。但是 final 物件裡的資料可以被改變。也就是說 final 物件的引用不能改變,但是裡面的值可以改變。
final 修飾符通常和 static 修飾符一起使用來建立類常量。

final 方法
類中的 final 方法可以被子類繼承,但是不能被子類修改。
宣告 final 方法的主要目的是防止該方法的內容被修改。
如下所示,使用 final 修飾符宣告方法。

final 類
final 類不能被繼承,沒有類能夠繼承 final 類的任何特性。

4.2.3 abstract 修飾符,用來建立抽象類和抽象方法。

抽象類
抽象類不能用來例項化物件,宣告抽象類的唯一目的是為了將來對該類進行擴充。
一個類不能同時被 abstract 和 final 修飾。如果一個類包含抽象方法,那麼該類一定要宣告為抽象類,否則將出現編譯錯誤。
抽象類可以包含抽象方法和非抽象方法。

抽象方法
抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。
抽象方法不能被宣告成 final 和 static。
任何繼承抽象類的子類必須實現父類的所有抽象方法,除非該子類也是抽象類。
如果一個類包含若干個抽象方法,那麼該類必須宣告為抽象類。抽象類可以不包含抽象方法。
抽象方法的宣告以分號結尾,例如:public abstract sample();。

4.2.4 synchronized 修飾符

synchronized 關鍵字宣告的方法同一時間只能被一個執行緒訪問。synchronized 修飾符可以應用於四個訪問修飾符。

4.2.5 transient 修飾符

序列化的物件包含被 transient 修飾的例項變數時,java 虛擬機器(JVM)跳過該特定的變數。
該修飾符包含在定義變數的語句中,用來預處理類和變數的資料型別。

4.2.5 volatile 修飾符

volatile 修飾的成員變數在每次被執行緒訪問時,都強制從共享記憶體中重新讀取該成員變數的值。而且,當成員變數發生變化時,會強制執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。
一個 volatile 物件引用可能是 null。

5. Java 迴圈結構

Java中有三種主要的迴圈結構:
while 迴圈
do…while 迴圈
for 迴圈

1、while 迴圈

while是最基本的迴圈,它的結構為:

while( 布林表示式 ) {
  //迴圈內容
}

2、do…while 迴圈

對於 while 語句而言,如果不滿足條件,則不能進入迴圈。但有時候我們需要即使不滿足條件,也至少執行一次。
do…while 迴圈和 while 迴圈相似,不同的是,do…while 迴圈至少會執行一次。

do {
       //程式碼語句
}while(布林表示式);

3、for迴圈

雖然所有迴圈結構都可以用 while 或者 do…while表示,但 Java 提供了另一種語句 —— for 迴圈,使一些迴圈結構變得更加簡單。
for迴圈執行的次數是在執行前就確定的。語法格式如下:

for(初始化; 布林表示式; 更新) {
    //程式碼語句
}

4、Java 增強 for 迴圈

Java5 引入了一種主要用於陣列的增強型 for 迴圈。
Java 增強 for 迴圈語法格式如下:

for(宣告語句 : 表示式)
{
   //程式碼句子
}

5、break 關鍵字

break 主要用在迴圈語句或者 switch 語句中,用來跳出整個語句塊。
break 跳出最裡層的迴圈,並且繼續執行該迴圈下面的語句。

6、continue 關鍵字

continue 適用於任何迴圈控制結構中。作用是讓程式立刻跳轉到下一次迴圈的迭代。
在 for 迴圈中,continue 語句使程式立即跳轉到更新語句。
在 while 或者 do…while 迴圈中,程式立即跳轉到布林表示式的判斷語句。

6. Java Number 類

一般地,當需要使用數字的時候,我們通常使用內建資料型別,如:byte、int、long、double 等。

然而,在實際開發過程中,我們經常會遇到需要使用物件,而不是內建資料型別的情形。為了解決這個問題,Java 語言為每一個內建資料型別提供了對應的包裝類。
所有的包裝類(Integer、Long、Byte、Double、Float、Short)都是抽象類 Number 的子類。

這裡寫圖片描述

Number 方法

1、xxxValue() 
將number物件轉換為xxx資料型別的值並返回。

2、compareTo()
將number物件與引數比較。

3、equals()
判斷number物件是否與引數相等

4、valueOf()
返回一個 Number 物件指定的內建資料型別

5、toString()
以字串形式返回值。

6、parseInt()
將字串解析為int型別。

7、abs()
返回引數的絕對值。

8、min()
返回兩個引數中的最小值。

9、max()
返回兩個引數中的最大值。

10、random()
返回一個隨機數。

7. Java String 類

字串廣泛應用 在Java 程式設計中,在 Java 中字串屬於物件,Java 提供了 String 類來建立和操作字串。

7.1 建立字串

建立字串最簡單的方式如下:

String str = "這是一個字串";


注意:String 類是不可改變的,所以你一旦建立了 String 物件,那它的值就無法改變了。
如果需要對字串做很多修改,那麼應該選擇使用 StringBuffer & StringBuilder 類。

7.2 字串長度

用於獲取有關物件的資訊的方法稱為訪問器方法。
String 類的一個訪問器方法是 length() 方法,它返回字串物件包含的字元數。

public class StringDemo {
    public static void main(String args[]) {
        String site = "www.runoob.com";
        int len = site.length();
        System.out.println( "菜鳥教程網址長度 : " + len );
   }
}

7.3 連線字串

String 類提供了連線兩個字串的方法:

string1.concat(string2);

更常用的是使用’+’操作符來連線字串,如:

"Hello," + " runoob" + "!"

7.4 建立格式化字串

我們知道輸出格式化數字可以使用 printf() 和 format() 方法。
String 類使用靜態方法 format() 返回一個String 物件而不是 PrintStream 物件。
String 類的靜態方法 format() 能用來建立可複用的格式化字串,而不僅僅是用於一次列印輸出。
如下所示:

System.out.printf("浮點型變數的的值為 " +
                  "%f, 整型變數的值為 " +
                  " %d, 字串變數的值為 " +
                  "is %s", floatVar, intVar, stringVar);

你也可以這樣寫

String fs;
fs = String.format("浮點型變數的的值為 " +
                   "%f, 整型變數的值為 " +
                   " %d, 字串變數的值為 " +
                   " %s", floatVar, intVar, stringVar);

7. Java 方法

7.1 方法概述

1、Java方法是語句的集合,它們在一起執行一個功能。

  • 方法是解決一類問題的步驟的有序組合
  • 方法包含於類或物件中
  • 方法在程式中被建立,在其他地方被引用

2、方法的優點

  • 使程式變得更簡短而清晰。
  • 有利於程式維護。
  • 可以提高程式開發的效率。
  • 提高了程式碼的重用性。

3、方法的命名規則

  • 必須以字母、’_’或’$’開頭。
  • 可以包括數字,但不能以它開頭。

7.2 方法的定義

一般情況下,定義一個方法包含以下語法:

修飾符 返回值型別 方法名(引數型別 引數名){
    ...
    方法體
    ...
    return 返回值;
}

方法包含一個方法頭和一個方法體。下面是一個方法的所有部分:

  • 修飾符:修飾符,這是可選的,告訴編譯器如何呼叫該方法。定義了該方法的訪問型別。

  • 返回值型別 :方法可能會返回值。returnValueType
    是方法返回值的資料型別。有些方法執行所需的操作,但沒有返回值。在這種情況下,returnValueType 是關鍵字void。

  • 方法名:是方法的實際名稱。方法名和引數表共同構成方法簽名。

  • 引數型別:引數像是一個佔位符。當方法被呼叫時,傳遞值給引數。這個值被稱為實參或變數。引數列表是指方法的引數型別、順序和引數的個數。引數是可選的,方法可以不包含任何引數。

  • 方法體:方法體包含具體的語句,定義該方法的功能。

7.3 方法的呼叫

Java 支援兩種呼叫方法的方式,根據方法是否返回值來選擇。
當程式呼叫一個方法時,程式的控制權交給了被呼叫的方法。當被呼叫方法的返回語句執行或者到達方法體閉括號時候交還控制權給程式。
當方法返回一個值的時候,方法呼叫通常被當做一個值。例如:

int larger = max(30, 40);

如果方法返回值是void,方法呼叫一定是一條語句。例如,方法println返回void。下面的呼叫是個語句:

System.out.println("歡迎訪問菜鳥教程!");

7.4 方法的過載

方法過載是指在一個類中定義多個同名的方法,但要求每個方法具有不同的引數的型別或引數的個數。Java的方法過載,就是在類中可以建立多個方法,它們可以有相同的名字,但必須具有不同的引數,即或者是引數的個數不同,或者是引數的型別不同。呼叫方法時通過傳遞給它們的不同個數和型別的引數來決定具體使用哪個方法

7.5 構造方法

構造方法是一種特殊的方法,它是一個與類同名且沒有返回值型別的方法。物件的建立就是通過構造方法來完成,其功能主要是完成物件的初始化。當類例項化一個物件時會自動呼叫構造方法。構造方法和其他方法一樣也可以過載。

8 Java繼承

繼承是java面向物件程式設計技術的一塊基石,因為它允許建立分等級層次的類。
繼承就是子類繼承父類的特徵和行為,使得子類物件(例項)具有父類的例項域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。

繼承的好處就是可以減少重複的程式碼,提高程式碼的維護性,程式碼也更加簡潔,提高程式碼的複用性。

類的繼承格式

在 Java 中通過 extends 關鍵字可以申明一個類是從另外一個類繼承而來的,一般形式如下:

 class 父類 {
}

class 子類 extends 父類 {
}

繼承的特性

  1. 子類擁有父類非private的屬性,方法。

  2. 子類可以擁有自己的屬性和方法,即子類可以對父類進行擴充套件。 子類可以用自己的方式實現父類的方法。

  3. Java的繼承是單繼承,但是可以多重繼承,單繼承就是一個子類只能繼承一個父類,多重繼承就是,例如A類繼承B類,B類繼承C類,所以按照關係就是C類是B類的父類,B類是A類的父類,這是java繼承區別於C++繼承的一個特性。

  4. 提高了類之間的耦合性(繼承的缺點,耦合度高就會造成程式碼之間的聯絡)。

繼承關鍵字

繼承可以使用 extends 和 implements 這兩個關鍵字來實現繼承,而且所有的類都是繼承於 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則預設繼承object(這個類在 java.lang 包中,所以不需要 import)祖先類

extends關鍵字

在 Java 中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以 extends 只能繼承一個類。

public class Animal { 
    private String name;   
    private int id; 
    public Animal(String myName, String myid) { 
        //初始化屬性值
    } 
    public void eat() {  //吃東西方法的具體實現  } 
    public void sleep() { //睡覺方法的具體實現  } 
} 

public class Penguin  extends  Animal{ 
}

implements關鍵字

使用 implements 關鍵字可以變相的使java具有多繼承的特性,使用範圍為類繼承介面的情況,可以同時繼承多個介面(介面跟介面之間採用逗號分隔)。

public interface A {
    public void eat();
    public void sleep();
}

public interface B {
    public void show();
}

public class C implements A,B {
}

super 與 this 關鍵字

super關鍵字:我們可以通過super關鍵字來實現對父類成員的訪問,用來引用當前物件的父類。

this關鍵字:指向自己的引用。

final關鍵字

final 關鍵字宣告類可以把類定義為不能繼承的,即最終類;或者用於修飾方法,該方法不能被子類重寫:

宣告類:
final class 類名 {//類體}

宣告方法:
修飾符(public,private,void,protected等) final 返回值型別 方法名(){//方法體}

注:例項變數也可以被定義為 final,被定義為 final 的變數不能被修改。被宣告為 final 類的方法自動地宣告為 final,但是例項變數並不是 final

構造器

子類不能繼承父類的構造器(構造方法或者建構函式),但是父類的構造器帶有引數的,則必須在子類的構造器中顯式地通過super關鍵字呼叫父類的構造器並配以適當的引數列表。
如果父類有無參構造器,則在子類的構造器中用super呼叫父類構造器不是必須的,如果沒有使用super關鍵字,系統會自動呼叫父類的無參構造器。

9 Java 重寫(Override)與過載(Overload)

9.1 重寫

重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫!
重寫的好處在於子類可以根據需要,定義特定於自己的行為。 也就是說子類能夠根據需要實現父類的方法。
重寫方法不能丟擲新的檢查異常或者比被重寫方法申明更加寬泛的異常。例如: 父類的一個方法申明瞭一個檢查異常 IOException,但是在重寫這個方法的時候不能丟擲 Exception 異常,因為 Exception 是 IOException 的父類,只能丟擲 IOException 的子類異常。

方法的重寫規則

  • 引數列表必須完全與被重寫方法的相同;

  • 返回型別必須完全與被重寫方法的返回型別相同;

  • 訪問許可權不能比父類中被重寫的方法的訪問許可權更低。例如:如果父類的一個方法被宣告為public,那麼在子類中重寫該方法就不能宣告為protected。

  • 父類的成員方法只能被它的子類重寫。

  • 宣告為final的方法不能被重寫。

  • 宣告為static的方法不能被重寫,但是能夠被再次宣告。

  • 子類和父類在同一個包中,那麼子類可以重寫父類所有方法,除了宣告為private和final的方法。

  • 子類和父類不在同一個包中,那麼子類只能夠重寫父類的宣告為public和protected的非final方法。

  • 重寫的方法能夠丟擲任何非強制異常,無論被重寫的方法是否丟擲異常。但是,重寫的方法不能丟擲新的強制性異常,或者比被重寫方法宣告的更廣泛的強制性異常,反之則可以。

  • 構造方法不能被重寫。

  • 如果不能繼承一個方法,則不能重寫這個方法。

Super關鍵字的使用

當需要在子類中呼叫父類的被重寫方法時,要使用super關鍵字。

9.2 過載(Overload)

過載(overloading) 是在一個類裡面,方法名字相同,而引數不同。返回型別可以相同也可以不同。
每個過載的方法(或者建構函式)都必須有一個獨一無二的引數型別列表。
只能過載建構函式。

過載規則

  • 被過載的方法必須改變引數列表(引數個數或型別或順序不一樣);
  • 被過載的方法可以改變返回型別;
  • 被過載的方法可以改變訪問修飾符;
  • 被過載的方法可以宣告新的或更廣的檢查異常;
  • 方法能夠在同一個類中或者在一個子類中被過載。
  • 無法以返回值型別作為過載函式的區分標準。

方法的重寫(Overriding)和過載(Overloading)是java多型性的不同表現,重寫是父類與子類之間多型性的一種表現,過載是一類中多型性的一種表現。

10 Java 多型

多型是同一個行為具有多個不同表現形式或形態的能力。多型性是物件多種表現形式的體現。

多型的優點

  1. 消除型別之間的耦合關係
  2. 可替換性
  3. 可擴充性
  4. 介面性
  5. 靈活性
  6. 簡化性

多型存在的三個必要條件

  • 繼承
  • 重寫
  • 父類引用指向子類物件

10 Java 抽象類

在面向物件的概念中,所有的物件都是通過類來描繪的,但是反過來,並不是所有的類都是用來描繪物件的,如果一個類中沒有包含足夠的資訊來描繪一個具體的物件,這樣的類就是抽象類。
抽象類除了不能例項化物件之外,類的其它功能依然存在,成員變數、成員方法和構造方法的訪問方式和普通類一樣。
由於抽象類不能例項化物件,所以抽象類必須被繼承,才能被使用。也是因為這個原因,通常在設計階段決定要不要設計抽象類。
父類包含了子類集合的常見的方法,但是由於父類本身是抽象的,所以不能使用這些方法。
在Java中抽象類表示的是一種繼承關係,一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

在Java語言中使用abstract class來定義抽象類。

抽象方法

如果你想設計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現由它的子類確定,那麼你可以在父類中宣告該方法為抽象方法。
Abstract關鍵字同樣可以用來宣告抽象方法,抽象方法只包含一個方法名,而沒有方法體。
抽象方法沒有定義,方法名後面直接跟一個分號,而不是花括號。

public abstract class Employee
{
   private String name;
   private String address;
   private int number;

   public abstract double computePay();

   //其餘程式碼
}

宣告抽象方法會造成以下兩個結果:

  • 如果一個類包含抽象方法,那麼該類必須是抽象類。
  • 任何子類必須重寫父類的抽象方法,或者宣告自身為抽象類。

繼承抽象方法的子類必須重寫該方法。否則,該子類也必須宣告為抽象類。最終,必須有子類實現該抽象方法,否則,從最初的父類到最終的子類都不能用來例項化物件。

抽象類總結規定

  1. 抽象類不能被例項化(初學者很容易犯的錯),如果被例項化,就會報錯,編譯無法通過。只有抽象類的非抽象子類可以建立物件。
  2. 抽象類中不一定包含抽象方法,但是有抽象方法的類必定是抽象類。
  3. 抽象類中的抽象方法只是宣告,不包含方法體,就是不給出方法的具體實現也就是方法的具體功能。
  4. 構造方法,類方法(用static修飾的方法)不能宣告為抽象方法。
  5. 抽象類的子類必須給出抽象類中的抽象方法的具體實現,除非該子類也是抽象類。

11 Java 抽象類

在面向物件程式設計方法中,封裝(英語:Encapsulation)是指,一種將抽象性函式介面的實作細節部份包裝、隱藏起來的方法。
封裝可以被認為是一個保護屏障,防止該類的程式碼和資料被外部類定義的程式碼隨機訪問。
要訪問該類的程式碼和資料,必須通過嚴格的介面控制。
封裝最主要的功能在於我們能修改自己的實現程式碼,而不用修改那些呼叫我們程式碼的程式片段。
適當的封裝可以讓程式碼更容易理解與維護,也加強了程式碼的安全性。

封裝的優點

  1. 良好的封裝能夠減少耦合。
  2. 類內部的結構可以自由修改。
  3. 可以對成員變數進行更精確的控制。
  4. 隱藏資訊,實現細節。

11 Java 介面

介面(英文:Interface),在JAVA程式語言中是一個抽象型別,是抽象方法的集合,介面通常以interface來宣告。一個類通過繼承介面的方式,從而來繼承介面的抽象方法。

介面並不是類,編寫介面的方式和類很相似,但是它們屬於不同的概念。類描述物件的屬性和方法。介面則包含類要實現的方法。
除非實現介面的類是抽象類,否則該類要定義介面中的所有方法。
介面無法被例項化,但是可以被實現。一個實現介面的類,必須實現介面內所描述的所有方法,否則就必須宣告為抽象類。另外,在 Java 中,介面型別可用來宣告一個變數,他們可以成為一個空指標,或是被繫結在一個以此介面實現的物件。

介面與類相似點:

  • 一個介面可以有多個方法。
  • 介面檔案儲存在 .java 結尾的檔案中,檔名使用介面名。
  • 介面的位元組碼檔案儲存在 .class結尾的檔案中。
  • 介面相應的位元組碼檔案必須在與包名稱相匹配的目錄結構中。

    介面與類的區別:

  • 介面不能用於例項化物件。
  • 介面沒有構造方法。
  • 介面中所有的方法必須是抽象方法。
  • 介面不能包含成員變數,除了 static 和 final 變數。
  • 介面不是被類繼承了,而是要被類實現。
  • 介面支援多重繼承。

介面特性

  • 介面中每一個方法也是隱式抽象的,介面中的方法會被隱式的指定為 public abstract(只能是 public abstract,其他修飾符都會報錯)。
  • 介面中可以含有變數,但是介面中的變數會被隱式的指定為 public static final 變數(並且只能是 public,用private 修飾會報編譯錯誤。
  • 介面中的方法是不能在介面中實現的,只能由實現介面的類來實現介面中的方法。

    抽象類和介面的區別

    1. 抽象類中的方法可以有方法體,就是能實現方法的具體功能,但是介面中的方法不行。
    2. 抽象類中的成員變數可以是各種型別的,而介面中的成員變數只能是 public static final 型別的。
    3. 介面中不能還有靜態程式碼塊以及靜態方法(用 static 修飾的方法),而抽象類是可以有靜態程式碼塊和靜態方法。
    4. 一個類只能繼承一個抽象類,而一個類卻可以實現多個介面。

介面的宣告

介面的宣告語法格式如下:

[可見度] interface 介面名稱 [extends 其他的類名] {
        // 宣告變數
        // 抽象方法
}

介面有以下特性:

  • 介面是隱式抽象的,當宣告一個介面的時候,不必使用abstract關鍵字。
  • 介面中每一個方法也是隱式抽象的,宣告時同樣不需要abstract關鍵子。
  • 介面中的方法都是公有的。

介面的實現

當類實現介面的時候,類要實現介面中所有的方法。否則,類必須宣告為抽象的類。
類使用implements關鍵字實現介面。在類宣告中,Implements關鍵字放在class聲明後面。
實現一個介面的語法,可以使用這個公式:

...implements 介面名稱[, 其他介面, 其他介面..., ...] ...

重寫介面中宣告的方法時,需要注意以下規則:

  • 類在實現介面的方法時,不能丟擲強制性異常,只能在介面中,或者繼承介面的抽象類中丟擲該強制性異常。
  • 類在重寫方法時要保持一致的方法名,並且應該保持相同或者相相容的返回值型別。
  • 如果實現介面的類是抽象類,那麼就沒必要實現該介面的方法。

在實現介面的時候,也要注意一些規則:

  • 一個類可以同時實現多個介面。
  • 一個類只能繼承一個類,但是能實現多個介面。
  • 一個介面能繼承另一個介面,這和類之間的繼承比較相似。

介面的繼承

一個介面能繼承另一個介面,和類之間的繼承方式比較相似。介面的繼承使用extends關鍵字,子介面繼承父介面的方法。

介面的多重繼承

在Java中,類的多重繼承是不合法,但介面允許多重繼承,。
在介面的多重繼承中extends關鍵字只需要使用一次,在其後跟著繼承介面。 如下所示:

public interface Hockey extends Sports, Event

標記介面

最常用的繼承介面是沒有包含任何方法的介面。
標識介面是沒有任何方法和屬性的介面.它僅僅表明它的類屬於一個特定的型別,供其他程式碼來測試允許做一些事情。
標識介面作用:簡單形象的說就是給某個物件打個標(蓋個戳),使物件擁有某個或某些特權。
例如:java.awt.event 包中的 MouseListener 介面繼承的 java.util.EventListener 介面定義如下:

package java.util;
public interface EventListener
{
}

沒有任何方法的介面被稱為標記介面。標記介面主要用於以下兩種目的:

  • 建立一個公共的父介面:

    正如EventListener介面,這是由幾十個其他介面擴充套件的Java API,你可以使用一個標記介面來建立一組介面的父介面。例如:當一個介面繼承了EventListener介面,Java虛擬機器(JVM)就知道該介面將要被用於一個事件的代理方案。

  • 向一個類新增資料型別:

    這種情況是標記介面最初的目的,實現標記介面的類不需要定義任何介面方法(因為標記介面根本就沒有方法),但是該類通過多型性變成一個介面型別。

12 Java 包(package)

為了更好地組織類,Java 提供了包機制,用於區別類名的名稱空間。

包的作用

1、把功能相似或相關的類或介面組織在同一個包中,方便類的查詢和使用。

2、如同資料夾一樣,包也採用了樹形目錄的儲存方式。同一個包中的類名字是不同的,不同的包中的類的名字是可以相同的,當同時呼叫兩個不同包中相同類名的類時,應該加上包名加以區別。因此,包可以避免名字衝突。

3、包也限定了訪問許可權,擁有包訪問許可權的類才能訪問某個包中的類。

Java 使用包(package)這種機制是為了防止命名衝突,訪問控制,提供搜尋和定位類(class)、介面、列舉(enumerations)和註釋(annotation)等。

包語句的語法格式為:

package pkg1[.pkg2[.pkg3…]];

13 Java 資料結構

Java工具包提供了強大的資料結構。在Java中的資料結構主要包括以下幾種介面和類:

  1. 列舉(Enumeration)
  2. 位集合(BitSet)
  3. 向量(Vector)
  4. 棧(Stack)
  5. 字典(Dictionary)
  6. 雜湊表(Hashtable)
  7. 屬性(Properties)

列舉(Enumeration)

 列舉(Enumeration)介面雖然它本身不屬於資料結構,但它在其他資料結構的範疇裡應用很廣。 列舉(The Enumeration)介面定義了一種從資料結構中取回連續元素的方式。

例如,列舉定義了一個叫nextElement 的方法,該方法用來得到一個包含多元素的資料結構的下一個元素。

位集合(BitSet)

位集合類實現了一組可以單獨設定和清除的位或標誌。
該類在處理一組布林值的時候非常有用,你只需要給每個值賦值一"位",然後對位進行適當的設定或清除,就可以對布林值進行操作了。

向量(Vector)

向量(Vector)類和傳統陣列非常相似,但是Vector的大小能根據需要動態的變化。
和陣列一樣,Vector物件的元素也能通過索引訪問。
使用Vector類最主要的好處就是在建立物件的時候不必給物件指定大小,它的大小會根據需要動態的變化。

棧(Stack)

棧(Stack)實現了一個後進先出(LIFO)的資料結構。
你可以把棧理解為物件的垂直分佈的棧,當你新增一個新元素時,就將新元素放在其他元素的頂部。
當你從棧中取元素的時候,就從棧頂取一個元素。換句話說,最後進棧的元素最先被取出。

字典(Dictionary)

字典(Dictionary) 類是一個抽象類,它定義了鍵對映到值的資料結構。
當你想要通過特定的鍵而不是整數索引來訪問資料的時候,這時候應該使用Dictionary。
由於Dictionary類是抽象類,所以它只提供了鍵對映到值的資料結構,而沒有提供特定的實現。

雜湊表(Hashtable)

Hashtable類提供了一種在使用者定義鍵結構的基礎上來組織資料的手段。
例如,在地址列表的雜湊表中,你可以根據郵政編碼作為鍵來儲存和排序資料,而不是通過人名。
雜湊表鍵的具體含義完全取決於雜湊表的使用情景和它包含的資料。

屬性(Properties)

Properties 繼承於 Hashtable.Properties 類表示了一個持久的屬性集.屬性列表中每個鍵及其對應值都是一個字串。
Properties 類被許多Java類使用。例如,在獲取環境變數時它就作為System.getProperties()方法的返回值。