抽象,接口和Object類

     在面向對象的概念中, 全部的對象都是經過類來表述的, 但並非全部的類都是用來描繪對象的, 若是一個類中麼有包含足夠的信息來描繪一類具體的對象, 這樣的類就是抽象類。 抽象類每每用來表徵對問題領域進行分析、 設計中得出抽象概念, 是對一系列看上去不一樣, 可是本質上相同的具體概念的抽象。抽象類對其共通行爲提供規範, 但並不實現, 而將其具體實現放到子類中完成, 經過「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
相關文章
相關標籤/搜索