在繼承的層次結構體系中,子類會變得越來越明確和具體,父類會變得更通用、更加明確。類的設計通常確保父類包含子類的共同特征,以至于沒有任何實例,這樣的類稱為抽象類。
有些方法不能在父類中實現,因為實現方法取決于子類的類型,這樣的方法稱為抽象方法(abstract method)。
抽象類不能使用new操作符創建它的實例。抽象方法由子類實現,一個包含抽象方法的類必須聲明為抽象類。抽象類的構造方法由PRotected 修飾,因為他只被子類實現。看了很多書本上的關于抽象方法的例子,抽象方法也是為了更好的實現多態,也是在為多態服務。
抽象類總結:
1. 有抽象方法的一定是抽象類,但是抽象類不一定包含抽象方法。子類如果不實現父類所有抽象方法,子類也必須是抽象的。父類是具體的,子類也可以是抽象的。子類還可以覆蓋父類的方法,并把它定義為抽象的,這種很少見,但是當父類的實現在子類中變得不合法時是很有用的。
2. 抽象方法是非靜態的。
3. 抽象類是不能用new操作符來初始化,但是可以定義他的構造方法,這個構造方法在他的子類的構造方法中調用。不能用new操作符創建對象,但是抽象類可以用作一種數據類型(這句話有點懵)。如下例:
GeometricObject[]objects = new GeometricObject[10];
objects[0] = newCircle();
感受下抽象類的好處吧:
public class TestGeometricObject { public static void main(String[] args) { GeometricObject geoObject1 = new Circle(5); GeometricObject geoObject2 = new Rectangle(5,3); System.out.println("The two objects have the same area? " + equalArea(geoObject1, geoObject2)); displayGeometricObject(geoObject1); displayGeometricObject(geoObject2); } /** A method for comparing the areas of twogeometric objects */ public static boolean equalArea(GeometricObject object1, GeometricObject object2) { return object1.getArea() == object2.getArea(); } /** A method for displaying a geometricobject */ public static void displayGeometricObject(GeometricObjectobject) { System.out.println(); System.out.println("The area is " + object.getArea()); System.out.println("The perimeter is " + object.getPerimeter()); } }
6.2接口
接口(interface)是一種與類相似的結構,只包含常量和抽象方法。接口在很多地方是與抽象類相似的,但是它的目的是指明多個對象的共同行為。
在java中,接口或多或少被看作是一種特殊的類。與抽象類相似,不能使用new操作符創建實例,但是大多數情況下,使用接口或多或少都有點像使用抽象類。當一個類實現接口時,該類實現了定義在接口中的所有帶確切簽名和返回類型的方法。
由于接口中所有數據域都是publicfinal static , 所有方法都是publicabstract,所以可以忽略這些修飾符。接口內定義的常量可以使用“接口名.常量名”來訪問。
判斷一下對錯:
Interface A {
voidprint() {};
}
Interface A {
Voidprint();
}
第二個例子是正確的。
6.3接口和抽象類的區別
| 變量 | 構造方法 | 方法 |
抽象類 | 無限制 | 子類通過構造方法鏈來調用構造方法 | 無限制 |
接口 | 變量必須是public static final,即常量 |
沒有構造方法 | 必須是public abstract |
另外接口可以實現多重繼承。所有的類共享根類Object,但是接口沒有共同的根。
抽象類和接口都是用來明確多個對象的共同特征。強是關系(is-a relationship)用抽象類建模。弱是(weak is-a relationship)它表明對象擁有某種屬性,弱是關系用接口來建模。推薦使用接口,因為接口可以定義不相關類共有的父類型,接口更加靈活。
Java中允許基本類型和包裝類型之間進行自動轉換。將基本類型轉換為包裝類對象的過程稱為裝箱(boxing),相反的過程稱為開箱(unboxing)。如果一個基本數值類型出現在需要對象的環境中,編譯器會將基本類型自動進行裝箱;如果一個對象出現在需要基本數值類型的環境中,編譯器將對對象自動開箱。
Interger[] intArray = {1,2,3}; boxing
System.out.println(intArray[0] +intArray[1]); unboxing
既可以用基本類型值也可以用表示數值的字符串來構造包裝類。包裝類沒有無參構造方法。所有包裝類的實例都是不可變的,這意味這一旦創建對象,它的內容就不能在改變。
數值包裝類有個有用的靜態方法valueOf(String s)。該方法創建一個新對象,并把它初始化為指定字符串表示的值。例如:Double d = Double.valueOf(“12.4”);
Interger類中的parseInt方法將一個數值字符串轉變成一個double值。比如:
Interger.parseInt(“11”,2) return 3;
每個數值包裝類都會實現在Number類中定義的抽象方法doubleValue()、intValue()等,從而返回包裝對象的值。
例一:
Interger i = Interger.parseInt(“23”,8)
int i =(Double.valueOf("23.4")).intValue();
第一句話是錯的,第二句話是對的。
例二:
Number n = new Interger(0);
Double d = (Double)n;
這兩行代碼可以編譯,但會導致運行錯誤,因為在運行時,JVM會嘗試把n 轉換成Double object, 但是n 是Integer實例。
例三:
Number x = 3; 正確
Double x = 3; 錯誤,3相當于newInteger(3)
Double x = 3.0; 正確
Int x = new Integer(3); 正確
新聞熱點
疑難解答