在面向對象的概念中, 全部的對象都是經過類來表述的, 但並非全部的類都是用來描繪對象的, 若是一個類中麼有包含足夠的信息來描繪一類具體的對象, 這樣的類就是抽象類。 抽象類每每用來表徵對問題領域進行分析、 設計中得出抽象概念, 是對一系列看上去不一樣, 可是本質上相同的具體概念的抽象。抽象類對其共通行爲提供規範, 但並不實現, 而將其具體實現放到子類中完成, 經過「abstract」關鍵字描述。java
舉個栗子:數組
定義一個平面圖形類Shape, 任何平面圖形都有周長和麪積。
ide
public abstract class Shape { double dim; public Shape(double dim){ this.dim = dim; } //抽象方法, 得到面積 public abstract void callArea(); //抽象方法, 得到周長 public abstract void callPerimeter(); }
抽象方法:this
從語法層面上看, 在java中凡是用到abstract修飾的類都是抽象類。在java中,若是某個方法沒有提供方法體實現,這種方法稱爲抽象方法。包含一個或者多個抽象方法的類叫作抽象類。
抽象類還能夠包含具體數據和具體的方法,也能夠包括構造方法。定義抽象類的目的是提供可由其子類共享的通常形式,子類能夠根據自身須要擴展抽象類。編碼
舉個栗子:spa
定義Shape的一個子類Circle來演示抽象類的使用
設計
1 public class Circle extends Shape{ 2 public Circle(double dim) { 3 super(dim); 4 } 5 //實現父類的抽象方法 6 @Override 7 public void callArea() { 8 System.out.println("圓的面積="+3.14*dim*dim); 9 } 10 //實現父類的抽象方法 11 @Override 12 public void callPerimeter() { 13 System.out.println("圓的周長="+2*3.14*dim); 14 } 15 }
抽象類除了使用abstract關鍵字定義實現, 還能夠經過繼承實現, 即該類在繼承一個抽象類或者接口的時候, 沒有爲全部抽象方法提供實現細節或方法主體時, 當前類也是抽象類。code
1 public abstract class Circle extends Shape{ 2 public Circle(double dim) { 3 super(dim); 4 } 5 //實現父類的抽象方法 6 @Override 7 public void callPerimeter() { 8 System.out.println("圓的周長="+2*3.14*dim); 9 } 10 }
接口:對象
抽象類是從多個類中抽象出來的模板, 若是將這種抽象進行的更完全, 則能夠抽象出一種更特殊的「抽象類」----接口(interface), 接口裏不能含有普通的方法, 接口裏的方法必須是抽象方法。blog
和類定義不一樣, 定義接口不能用class關鍵字, 而是使用interface關鍵字, 其語法爲:
1 [訪問修飾符] interface 接口名稱[extends 父類接口名錶]{ 2 [訪問修飾符] final 數據類型 常量名 = 值; //常量聲明 3 [訪問修飾符] 返回值類型 方法名(參數列表); //抽象方法 4 }
舉個栗子:
1 public interface Shape { 2 //面積 3 double area = 100.0; 4 //畫出本身 5 void draw(); 6 //獲得面積 7 double getArea(); 8 }
由於全部定義在接口中的常量都默認爲public static final , 全部定義在接口中的方法默認爲public abstract。 因此能夠不用修飾符限定它們。
接口的實現:
多個無關的類能夠實現同一個接口;
一個類可實現多個無關的接口;
<modifier> class <name> [extends <superclass>] [implements<interface>[,<interface>]*] { <declarations>* }
由於Java 是基於單根繼承的, 即Java 繼承中, 只能繼承一個類, 在Java中,能夠經過接口來模擬多繼承;
自定義Circle類, 實現Shape接口:
public class Circle implements Shape{ @Override public void draw() { System.out.println("draw a circle..."); } @Override public double getArea() { //area = 200.0;//error 常量的值不可被改變 return area; } public static void main(String[] args) { Shape shape = new Circle(); shape.draw(); System.out.println(shape.getArea()); } }
接口實現的一些注意事項:
在類的聲明部分,用implements關鍵字聲明將要實現那些接口;
- 接口裏的抽象方法訪問修飾符都已指定爲public,所以,類在實現方法時,必須顯示地使用public修飾符,不然,將縮小接口定義方法的訪問控制範圍。
- 若是實現某接口的類不是abstract類,則在類的定義部分裏必須所有實現指定接口的全部抽象方法,並且方法頭部分應該與接口中的定義徹底一直;
- 若是實現某接口的類是abstract類,則它能夠不實現該接口全部的方法,但其非abstract的子類必須有全部抽象方法的實現的方法體;
Object類
Object類是全部Java類的基類或根類, 全部類的對象(包括數組對象)都繼承了Object的方法。
若是在類的聲明中未使用extends關鍵字指明其基類, 則默認基類爲Object類。
1 public class Animal{ 2 ......... 3 } 4 等價於: 5 public class Animal extends Object{ 6 ......... 7 }
Object類經常使用方法 :
方法 | 含義 |
boolean equals(Object obj) | 指示某個其餘對象是否與此對象「相等」; |
String toString() | 返回該對象的字符串表示; |
int hashCode() | 返回該對象的哈希碼值; |
Object clone() | 建立並返回此對象的一個副本; |
void finalize() | 當垃圾回收器肯定不存在對該對象的更多引用 時, 由對象的垃圾回收器調用此方法; |
toString 方法:
- Object類中定義有public String toString()方法,其返回值是String類型,描述當前對象有關的信息;
- 在進行String與其餘類型數據的鏈接操做時(如:System.out.println(「info」+person)),將自動調用該對象類的toString(()方法;
- 能夠根據須要在用戶自定義類型中重寫toString()方法;
- 一個字符串和另一種類型鏈接的時候,另一種類型會自動轉換成String類型,而後再和字符串鏈接;
舉個栗子:
1 public class TestToString { 2 public static void main(String[] args) { 3 Duck d = new Duck(); 4 5 // 輸出的結果: 6 Duck@e0a386 7 System.out.println(d); 8 } 9 }
如果沒有重寫toString方法, 那麼輸出來的默認的字符串內容是」類名+哈希編碼」;
重寫toString方法例子 :
爲了使打印出來的信息能看懂, 那麼在Duck類裏面把繼承下來的toString()方法進行重寫:
public class Duck { //重寫object類的toString()方法 @Override public String toString() { return "I'm a cool Duck"; } public static void main(String[] args) { Duck d = new Duck(); System.out.println(d); // 輸出的結果: I'm a cool Duck } }
equals 方法:
判斷兩個對象是否相等, 是要看兩個對象引用是否指向同一個對象,「是」則返回true,「否」則返回false。
Java語言規範要求equals方法具備如下特色:
- 自反性 對於任何非空引用值,x.equals(x)都應返回true;
- 對稱性 對於任何非空引用值x和y,當且僅當y.equals(x)返回true時,x.equals(y)才應返回true;
- 傳遞性 對於任何非空引用值x、y和z,若是x.equals(y)返回true,而且y.equals(z)返回true,那麼x.equal(z)應返回true;
- 一致性 對於任何非空引用值x和y,屢次調用x.equals(y)始終返回true或始終返回false,前提是對象上equals比較中所用的信息沒有被修改;
- 對於任何非空引用值,x,x.equals(null)都應返回false;
Object下的equals方法源碼:
1 public boolean equals(Object obj) { 2 return (this == obj); 3 }
一般自定義的對象, 須要重寫equals方法, 比較的結果纔會爲真。
舉個栗子 equals :
1 public class TestEquals{ 2 public static void main(String args[]){ 3 String s1=new S ring("hello"); 4 String s2=new String("hello"); 5 System.out.println(" 1==c2: "+(s1==s2));//false 6 System.out.println("s1.equals(s2): "+s1.equals(s2));//true 7 } 8 }
equals與「==」 :
「==」操做符的做用:
1) 用於基本數據類型的比較;
2) 判斷引用是否指向堆內存的同一塊地址;
equals的做用:
用於判斷兩個變量是不是對同一個對象的引用, 即堆中的內容是否相同, 返回值爲布爾類型;
舉個栗子:
1 String s1 = new String("java); 2 String s2 = new String("java"); 3 System.out.println(s1==s2); //false 4 System.out.println(s1.equals(s2)); //true
同一個對象, 「==」和equasl結果相同 :
1 String s1 = new String("java"); 2 String s2 = s1; 3 System.out.println(s1==s2); //true 4 System.out.println(s1.equals(s2)); //true
若是值相同, 對象就相同, 因此「==」和equals結果同樣 :
1 String s1 = "java"; 2 String s2 = "java"; 3 System.out.println(s1==s2); //true 4 System.out.println(s1.equals(s2)); //true