前幾篇是Java的入門篇,主要是瞭解一下Java語言的相關知識,從本篇開始是Java的進階篇,這部份內容能夠幫助你們用Java開發一些小型應用程序,或者一些小遊戲等等。ide
本篇的主題是接口、繼承與多態,在看下面的內容以前,首先須要瞭解一下繼承和多態。繼承機制的使用能夠複用一些定義好的類,減小重複代碼的編寫;多態機制的使用能夠動態調整對象的調用,下降對象之間的依存關係。有了這些概念,再來看接口是作什麼用的。測試
首先咱們須要知道,Java語言只支持單重繼承,不支持多繼承。這句話的意思就是一個類只能有一個父類,但咱們常常須要使用多繼承來解決問題,因此Java語言提供了接口來實現類的多重繼承功能。this
Java中使用interface來定義一個接口,接口定義與類類似(類的定義用的是class),下面直接上例子。spa
public interface ICalculate { final float PI = 3.1415f; // 定義常量PI,表示圓周率 float getArea(float r); // 定義用於計算面積的方法getArea() float getCircumference(float r); // 定義用於計算周長的方法getCircumference()
}
從上述代碼能夠看出,interface是定義了一個接口,接口名爲ICalculate(接口通常能夠用大寫字母「I」開頭),在接口中能夠定義變量和方法,但須要注意的是這裏的方法都不能寫方法體,也即方法名後直接加「;」,而方法的實現是寫到實現接口的類中的。還有一點須要注意的是,接口中的全部方法都必須在實現了該接口的類中實現(能夠空實現)。code
接下來演示一下Eclipse中如何建立一個接口。對象
(1)首先在包上右鍵new一個Interfaceblog
(2)填寫接口名並肯定繼承
(3)編寫代碼接口
上面定義了一個接口,但要實現接口須要在類中用implements關鍵字,下面直接看例子,對應的接口是上例中的ICalculate。遊戲
1 public class Calculate implements ICalculate { 2 3 @Override 4 public float getArea(float r) { 5 float area = PI*r*r; // 計算圓面積並賦值給area 6 return area; // 返回area的值 7 } 8 9 @Override 10 public float getCircumference(float r) { 11 float circumference = 2*PI*r; // 計算圓周長並賦值給circumference 12 return circumference; // 返回circumference的值 13 } 14 15 }
Eclipse中建立步驟以下:
(1)填寫類名,點擊Add添加接口
(2)輸入查找接口並肯定
(3)接口導入後點擊肯定,就能夠看到以下界面,填寫相應代碼便可(建立的每一個接口中的方法都必須實現,能夠空實現,因此不能刪除這裏的任何一個方法)
一個類能夠實現多個接口,寫法就是implements後的接口間以「,」隔開便可。若是變量衝突,則經過「接口名.變量」來明確指定變量的接口。
在Java中,使用extends關鍵字實現繼承,extends後跟的是父類名,也就是它從哪一個類繼承過來的,而用extends的這個類自己稱爲子類。
下面舉個簡單的例子,在生物學中,鴿子屬於鳥的一種,因此鳥是父類,鴿子是子類。
父類:
public class Bird { String color = "灰色"; // 顏色 String skin = "羽毛"; // 皮毛 }
子類:
public class Pigeon extends Bird { public static void main(String[] args) { Pigeon pigeon = new Pigeon(); System.out.println(pigeon.color); } }
簡單來講就是,若是子類方法名和父類方法名相同,那麼子類就不能繼承父類的方法,此時稱子類的方法重寫了父類的方法。重寫也可稱爲覆蓋。
舉個簡單的例子,這是一個動物類,實現了一個voice方法:
public class Animal { public Animal() {} public void voice() { System.out.println("make some voice.."); } }
建立一個Animal類的子類Dog,重寫voice方法發出狗叫:
public class Dog extends Animal{ public Dog() {} @Override public void voice(){ System.out.println("woof..."); } }
再建立一個Animal類的子類Cat,重寫voice方法發出貓叫:
public class Cat extends Animal { public Cat() {} @Override public void voice(){ System.out.println("nya..."); } }
此時調用dog和cat中的方法都不會出現「make some voise..」字樣,而是對應的狗叫和貓叫。
但若是此時再建立一個Animal類的子類,但不重寫方法,此時輸出爲父類Animal中voice方法的內容,建立一個子類Fish以下:
public class Fish extends Animal{ public Fish() {} }
下面建立一個Zoo類,來調用上述幾個方法測試一下:
public class Zoo { public static void main(String[] args) { Dog dog = new Dog(); dog.voice(); Cat cat = new Cat(); cat.voice(); Fish fish = new Fish(); fish.voice(); } }
運行結果以下:
從運行結果能夠看出,因爲Dog類和Cat類都重寫了父類的方法voice(),因此執行其相應的方法,而Fish類中沒有重寫,因此執行的是父類中的方法。
子類能夠調用父類聲明的構造方法,可是必須在子類的構造方法中使用super關鍵字來調用;若是想在子類中操做父類中被隱藏的成員變量和被重寫的成員方法,也能夠使用super關鍵字。這些在之後的項目中會出現,這裏就不舉例了,若是使用Java編譯器的話,須要使用super關鍵字但未使用時編譯器會有錯誤提示。
在Java中,一般使用方法的重載和重寫實現類的多態性。
重寫在上面已經介紹過了,而方法的重載是指在一個類中出現多個方法名相同,但參數個數或參數類型不一樣的方法,下面舉個關於重載的例子。
好比求圓形和矩形的面積,是兩個名稱爲getArea()的方法,它們的參數個數不一樣,以下:
// 求圓形面積 public float getArea(float r) { float area = PI*r*r; return area; } // 求矩形面積 public float getArea(float a, float b) { // 重載getArea()方法 float area = a*b; return area; }
再好比添加一個學生的信息,是兩個名稱爲setStudent()方法,它們的參數類型不一樣,以下:
// 添加學生號 public void setStudent(int ID) { this.stu_id = ID; } // 添加求學生姓名 public void setStudent(String name) { this.stu_name = name; }
須要注意的是,在進行方法的重載時,方法返回值的類型不能做爲區分方法的標誌。