Java是一門面向對象語言,能夠看出「對象」在Java有着舉足輕重的位置。那麼,「對象」從何而來呢?那必須是丈母孃造出來的,下面咱們就先來講說這個丈母孃——類。html
類能夠當作是建立Java對象的模板,下面簡單定義一個類:java
public class People{ String name; // 成員變量 int age; String weight; static final double weeks = 9.5; // 類變量 void eat(){ } void sleep(){ } void play(){ } Public People { // 這是一個構造方法 int count = 0; // 局部變量 } }
一個類能夠包含如下類型變量:編程
static
類型每一個類都有構造方法。若是沒有顯示地爲類定義構造方法,Java編譯器將會爲該類提供一個默認構造方法。yii
在建立一個對象的時候,至少要調用一個構造方法。構造方法的名稱必須與類同名,一個類能夠有多個構造方法。函數
public class Puppy{ public Puppy(){ } public Puppy(String name){ // 這個構造器僅有一個參數:name } }
對象時根據類建立的。在Java中,使用關鍵字new
來建立一個新的對象。建立對象須要如下三步:this
new
來建立一個對象new
建立對象時,會調用構造方法初始化對象下面是一個建立對象的例子:.net
public class Puppy{ public Puppy(String name){ //這個構造器僅有一個參數:name System.out.println("小狗的名字是 : " + name ); } public static void main(String[] args){ // 下面的語句將建立一個Puppy對象 Puppy myPuppy = new Puppy( "tommy" ); } }
編譯並運行上面的程序,會打印出下面的結果:設計
小狗的名字是:tommy
下面的例子展現如何訪問實例變量和調用成員方法:指針
public class Puppy{ int puppyAge; public Puppy(String name){ // 這個構造器僅有一個參數:name System.out.println("小狗的名字是 : " + name ); } public void setAge( int age ){ puppyAge = age; // 當形參`age`也是puppyAge時,須要用this:this.puppyAge = puppyAge } public int getAge( ){ System.out.println("小狗的年齡爲 : " + puppyAge ); return puppyAge; } public static void main(String[] args){ /* 建立對象 */ Puppy myPuppy = new Puppy( "tommy" ); /* 經過方法來設定age */ myPuppy.setAge( 2 ); /* 調用另外一個方法獲取age */ myPuppy.getAge( ); /*你也能夠像下面這樣訪問成員變量 */ System.out.println("變量值 : " + myPuppy.puppyAge ); } }
編譯並運行上面的程序,產生以下的結果:code
小狗的名字是 : tommy 小狗的年齡爲 : 2 變量值 : 2
Java的繼承是一種機制,表示爲一個對象獲取父對象的全部屬性和行爲。
繼承是類與類之間的關係,是一個很簡單很直觀的概念,與現實世界中的繼承(例如兒子繼承父親財產)相似。
Java中的繼承,能夠建立基於現有類構建新的類。 當你從現有類繼承時,就能夠重複使用父類的方法和字段,也能夠在繼承的新類中添加新的方法和字段。
對於方法覆蓋(所以能夠實現運行時的多態性),提升代碼可重用性。在Java中,子類可繼承父類中的方法,而不須要從新編寫相同的方法。但有時子類並不想原封不動地繼承父類的方法,而是想做必定的修改,這就須要採用方法的重寫(覆蓋)。
Java類繼承的語法示例:
class Super { } class Sub extends Super { }
extends
關鍵字表示從現有類派生建立的新類。extends
的含義是增長功能。在Java的術語中,被繼承的類稱爲父類或超類,新類稱爲子類。
Java繼承示例
如上圖所示,Programmer
是子類,Employee
是超類。 兩個類之間的關係是Programmer IS-A Employee
. 它表示 Programmer
是一種 Employee
的類型。
參考下面示例代碼實現:
class Employee { float salary = 40000; } class Programmer extends Employee { int bonus = 10000; public static void main(String args[]) { Programmer p = new Programmer(); System.out.println("Programmer salary is:" + p.salary); System.out.println("Bonus of Programmer is:" + p.bonus); } }
執行上面代碼獲得如下結果:
Programmer salary is:40000.0 Bonus of programmer is:10000
在上面的例子中,Programmer
對象能夠訪問自身類以及Employee
類的字段,即提升了代碼可重用性。
默認的: 不使用任何修飾符聲明的屬性和方法,對同一個包內的類是可見的。接口裏的變量都隱式聲明爲
public static final
,而接口裏的方法默認狀況下訪問權限爲public
在類的基礎上,在Java中能夠有三種類型的繼承:單一,多級和分層繼承。在Java的編程中,僅能經過接口支持多繼承和混合繼承。
注意:Java中的類不支持多繼承
當一個類擴展多個類,即被稱爲多繼承。例如:
問題:爲何在Java中不支持多繼承?
爲了下降複雜性並簡化語言,Java中不支持多重繼承。想象一個:A,B和C是三個類。 C類繼承A和B類。 若是A和B類有相同的方法,而且從子類對象調用它,A或B類的調用方法會有歧義。
由於編譯時錯誤比運行時錯誤好,若是繼承2個類,Java會在編譯時報告錯誤。 因此不管子類中是否有相同的方法,都會有報告編譯時錯誤。
注意:構造方法不能被繼承,掌握這一點很重要。 一個類能獲得構造方法,只有兩個辦法:編寫構造方法,或者根本沒有構造方法,類有一個默認的構造方法。
在面向對象的概念中,全部的對象都是經過類來描繪的,可是反過來,並非全部的類都是用來描繪對象的,若是一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。
在Java中抽象類表示的是一種繼承關係,一個類只能繼承一個抽象類,而一個類卻能夠實現多個接口。
因爲抽象類不能實例化對象,因此抽象類必須被繼承,才能被使用。也是由於這個緣由,一般在設計階段決定要不要設計抽象類。
在Java中使用abstract
關鍵字來定義抽象類。以下示例:
//example of abstract class that have method body abstract class Bike { Bike() { System.out.println("bike is created"); } abstract void run(); void changeGear() { System.out.println("gear changed"); } } class Honda extends Bike { void run() { System.out.println("running safely.."); } } class TestAbstraction2 { public static void main(String args[]) { Bike obj = new Honda(); obj.run(); obj.changeGear(); } }
注意到該Bike
類沒有什麼不一樣,儘管該類是抽象類,可是它仍然有成員變量,抽象方法,方法體,構造函數甚至main()
方法。
執行上面的代碼:
bike is created running safely.. gear changed
若是你想設計這樣一個類,該類包含一個特別的成員方法,該方法的具體實現由它的子類肯定,那麼你能夠在父類中聲明該方法爲抽象方法。
Abstract 關鍵字一樣能夠用來聲明抽象方法,抽象方法只包含一個方法名,而沒有方法體。
抽象方法沒有實現,方法名後面直接跟一個分號,而不是花括號。
public abstract class Employee { private String name; private String address; private int number; public abstract double computePay(); //其他代碼 }
聲明抽象方法會形成如下兩個結果:
繼承抽象方法的子類必須重寫該方法。不然,該子類也必須聲明爲抽象類。最終,必須有子類實現該抽象方法,不然,從最初的父類到最終的子類都不能用來實例化對象。
若是Salary
類繼承了Employee
類,那麼它必須實現computePay()
方法:
/* 文件名 : Salary.java */ public class Salary extends Employee { private double salary; // Annual salary public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } //其他代碼 }
注意: 抽象類中不能有抽象構造方法或抽象靜態方法
參考:Java抽象類
抽象類除了不能實例化對象以外,類的其它功能依然存在,成員變量、成員方法和構造方法的訪問方式和普通類同樣。
抽象類不能被實例化,若是被實例化,就會報錯,編譯沒法經過。只有抽象類的非抽象子類能夠被實例化
普通類和抽象類均可以被繼承,可是抽象類被繼承後子類必須重寫繼承的方法,除非自類也是抽象類
抽象類中不必定含有抽象方法,可是有抽象方法的類一定時抽象類
抽象類中的抽象方法只是聲明,不包含方法體,即不能給出方法的具體實現
構造方法、類方法(用static
修飾的方法)不能聲明爲抽象方法
總之一句話,抽象類只是一種比較特殊的普通類。我以爲這篇文章解釋的不錯,大概意思就是:抽象類嚴格規定了幾個你必須作的事情,好比:不能實例化、子類必須實現父類,除非子類也是抽象類。你不這樣作就會出錯,這種嚴謹的作法比人爲規定的更加有效。
定義:接口在Java中是一個抽象類型,是抽象方法的集合。一個類經過繼承接口的方式,從而繼承接口的抽象方法。
接口一般以interface
來聲明,能夠看作是一種特殊的抽象類。一個類經過繼承接口的方式,從而來繼承接口的抽象方法。
接口並非類,編寫接口的方式和類很類似,可是它們屬於不一樣的概念。類描述對象的屬性和方法。接口則包含類要實現的方法。
接口沒法被實例化,可是能夠被實現。一個實現接口的類,必須實現接口內所描述的全部方法,不然就必須聲明爲抽象類。另外,在 Java 中,接口類型可用來聲明一個變量,他們能夠成爲一個空指針,或是被綁定在一個以此接口實現的對象。
接口的聲明語法格式以下:
public interface 接口名稱 [extends 其餘的接口名] { // 聲明變量 // 抽象方法 }
接口有如下幾個特徵:
注:JDK 1.8 之後,接口裏能夠有靜態方法和方法體
當類實現接口的時候,類要實現接口中的全部的方法。不然,類必須聲明爲抽象類
類使用implements關鍵字實現接口。在類聲明中,Implements關鍵字放在class聲明後面。
實現一個接口的語法,可使用這個公式:
...implements 接口名稱[, 其餘接口名稱, 其餘接口名稱..., ...] ...
下面是一個Java的接口示例:
interface printable { void print(); } class A6 implements printable { public void print() { System.out.println("Hello, Interface"); } public static void main(String args[]) { A6 obj = new A6(); obj.print(); } }
執行上面的代碼,結果以下:
Hello,Interface
.java
結尾的文件中,文件名使用接口名.class
結尾的文件中static
和final
變量public static final
類型的參考: