抽象類和接口
一、抽象類
在類層次結構中,類的位置越高,其定義的抽象程度也就越高。在定義類層次結構中的過程中,有一些類确定了子類的通用的行為和屬性,而且這些類不能被執行個體化用限定符abstract來聲明。這些類稱為抽象類。
l 抽象類可以包含正常類能夠包含的任何東西,包括構造方法,因為子類可能需要繼承這種方法。
l 抽象類也可以包含抽象方法,也就是沒有實作的方法,而這些方法在子類中被實作。不能在非抽象類中聲明抽象方法。
l 如果一個抽象類中除了抽象方法外什麼都沒有,則最好使用接口。
二、接口
與抽象類和抽象方法一樣,接口也是提供了其他類要實作的行為模闆。
使用和實作接口l 要使用接口,可以在類定義中包含關鍵字implements
l 包含接口後,必須實作該接口中的所有方法,而不能有選擇地實作其中的某些。
l 類實作接口後,子類将繼承該接口中的所有方法,并可以覆寫或重載它們。
l 若類繼承了一個實作了某一接口的超類,則不必在本類中又implements一次。
l 要在類中使用多個接口,隻需要将它們的名稱用逗号分開。
使用多個接口時如果兩個接口定義了相同的方法,則應注意以下規則:l 如果兩個方法的特征标相同,可以在類中實作一個方法,其定義能夠滿足兩個接口。
l 如果方法的參數清單不同,則是一種簡單的方法重載:實作兩種方法特征标,分别滿足兩個接口的需要。
l 如果方法的參數清單相同,但傳回值不同,則無法建立一個能夠滿足兩個接口的方法。這時,編譯會出錯。
建立接口的規定:
l 建立接口要用interface,而不是class。
l 如果接口前沒有限定符,則自動被轉換為abstract和public的,而且不能在接口内将方法聲明為私有的或是保護的。
l 除了方法外,接口還可以包含變量,但它們必須是公有、靜态和final的(常量)。或者不使用限定符,這樣會自動聲明為這些限定,而且變量須指派。
l 如果聲明接口時沒有使用pulbic,則接口不會自動将方法轉換為公有和抽象的,也不會将常量轉換為公有的。而非公有接口的方法和常量也是非公有的,這些方法和常量隻能被同一個包中的類和其他接口使用。
l 與類一樣,接口也可以屬于某個包。接口還可以導入其他包中的接口和類,就像類一樣。
l 接口可以繼承另一個接口,此時‘子接口’将獲得‘超接口’中聲明的所有方法定義和常量。這時要使用extends擴充。
l 另外,不同于類,接口可以多重繼承,新接口将包含其父接口中的方法和常量。(多繼承限制參見本話題之上的一個話題)
三、執行個體
建立一個網上商店,應用程式Storefront使用了包、通路控制、接口和封裝。主要處理兩項任務:
l 根據庫存量計算每種商品的銷售價格;
l 按照銷售價格對商品排序;
Item類
package com.prefect.ecommerce;
/**
* 本類實作了Comparable接口,這個接口使得對類的對象進行排序更容易。
* 這個接口隻有一個方法compareTo(Object),傳回一個整數,功能是比較
* 兩個對象:
* 若目前對象應排列在另一個之前,傳回-1
* 若目前對象應排列在另一個之後,傳回1
* 兩個對象相等,則傳回0
* */
public class Item implements Comparable
{
private String id;
private String name;
private double retail;
private int quantity;
private double price;
Item(String id,String name,String retail,String quan)
{
this.id = id;
this.name = name;
this.retail = Double.parseDouble(retail);
this.quantity = Integer.parseInt(quan);
if(this.quantity > 400)
{
this.price = this.retail * .5D;
}
else if(this.quantity > 200)
this.price = this.retail * .6D;
else
this.price = this.retail * .7D;
//對price四舍五入,Math.floor()表示将小數舍入為與之最接近且不大于它的整數
//并傳回double
price = Math.floor(price * 100 + .5)/100;
}
//compareTo()方法需要決定根據哪個執行個體變量來對對象進行排序,這裡根據price
public int compareTo(Object o)
Item temp = (Item)o;
if(this.price < temp.price)
return 1;
else if(this.price > temp.price)
return -1;
return 0;
public String getId()
return id;
public String getName()
return name;
public double getPrice()
return price;
public int getQuantity()
return quantity;
public double getRetail()
return retail;
}
Storefont類
*用于管理商店中的商品,每一種商品都是一個Item對象,他們被存儲在連結清單中
*/
import java.util.Collections;
import java.util.LinkedList;
public class Storefont
//建立一個連結清單
private LinkedList catalog = new LinkedList();
//将item加入到連結清單中
public void addItem(String id, String name, String price, String quant)
Item it = new Item(id, name, price, quant);
//在連結清單中添加對象的方法
catalog.add(it);
//傳回目前的item,使用索引i來讀取他們
public Item getItem(int i)
//讀取連結清單中的索引
return (Item) catalog.get(i);
//傳回連結清單中的對象數
public int getSize()
//連結清單的大小
return catalog.size();
public void sort()
//此方法對連結清單和其他資料結果中的對象進行排序,期間将調用對象的
//comparaTo()方法來确定排序
Collections.sort(catalog);
}
GiftShop類
public class GiftShop
public static void main(String[] args)
Storefont store = new Storefont();
//添加商品
store.addItem("C01","MUG","9.99","150");
store.addItem("C02","LG MUG","12.99","82");
store.addItem("C03","MOUSEPAD","10.49","800");
store.addItem("D01","T SHIRT","16.99","90");
//進行排序
store.sort();
//輸出排序後的結果
for(int i = 0 ; i < store.getSize() ; i++)
Item show = (Item)store.getItem(i);
System.out.println("\nItem ID:" + show.getId()
+ "\nName:" + show.getName()
+ "\nRetail Price:$" + show.getRetail()
+ "\nPrice:$" + show.getPrice()
+ "\nQuantity:" + show.getQuantity());
運作結果
Item ID:D01
Name:T SHIRT
Retail Price:$16.99
Price:$11.89
Quantity:90
Item ID:C02
Name:LG MUG
Retail Price:$12.99
Price:$9.09
Quantity:82
Item ID:C01
Name:MUG
Retail Price:$9.99
Price:$6.99
Quantity:150
Item ID:C03
Name:MOUSEPAD
Retail Price:$10.49
Price:$5.25
Quantity:800