一.認識抽象類
1.簡介
假設要編寫一個計算圓、三角形和矩形的面積與周長的程序。若按照前面所學的方式編程,就必須定義3個類:圓類、三角形類、矩形類,它們之間沒有繼承關係。程序寫好之後雖然能執行,但從代碼的整體結構來看,前面三個類的許多共同屬性和操作沒有好好地利用,需要重複的編寫代碼,降低了程序的開發效率,且使出現錯誤的機會增加。
仔細分析上面3個例子的類,可以看到這三個類都要計算面積與周長,雖然公式有所不同,但是目標是相同的。因此,可以把這三個類抽象出一個父類,在父類裏面定義圓,三角形和矩形3個類共同的成員屬性及成員方法。把計算面積和周長的成員方法名放在父類中說明,再在子類中將具體方法實現。
抽象類是它所有子類的公共屬性集合,是包含一個或多個抽象方法的類。使用抽象類的一大優點是可以充分利用這些公有屬性來提高開發和維護程序的效率。
2.抽象方法
在瞭解抽象類之前,先來了解一下抽象方法。抽象方法是一種特殊的方法:它只有聲明,而沒有具體的實現。抽象方法的聲明格式爲:
abstract 返回值類型 方法名 (【參數列表】);
例如:abstract void eat();
注意:抽象方法沒有定義的方法體,方法名後面直接跟一個分號,而不是花括號。抽象方法必須用abstract關鍵字進行修飾。
3.定義抽象類
如果一個類含有抽象方法,則稱這個類爲抽象類,抽象類必須在類前用abstract關鍵字修飾。
例如:
//抽象類Animal
public abstract class Animal{
//抽象方法shout
public abstract void shout();
}
包含抽象方法的類稱爲抽象類,但並不意味着抽象類中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變量和普通的成員方法。注意,抽象類和普通類的主要有三點區別:
1)抽象方法必須爲public或者protected(因爲如果爲private,則不能被子類繼承,子類便無法實現該方法),缺省情況下默認爲public.
2)抽象類不能用來創建對象,需要子類採用向上轉型的方式處理;
3)如果一個類繼承於一個抽象類,則子類必須重寫父類的全部抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義爲爲abstract類。
4)抽象類不能用final關鍵字聲明,因爲抽象類必須有子類,而final定義的類不能有子類。
抽象類實例:
//抽象類Animal
abstract class Animal{
//抽象方法shout
public abstract void shout();
}
//子類Dogs繼承抽象父類Animal
class Dogs extends Animal{
//子類重寫抽象類的抽象方法
public void shout(){
System.out.println(" 狗會汪汪汪地叫");
}
}
public class Test{
public static void main(String[] args){
//抽象類通過子類向上轉型實例化
Animal animal = new Dogs();
animal.shout();
}
}
注意:
抽象類是不能直接實例化的,一次Animal animal = new Animal()在編譯的時候會報錯,需要採用向上轉型的方式來實例化。其實抽象類比普通類只是多了一些抽象方法,其他組成部分和普通類完全一樣。
二.接口
1.接口聲明
接口是比抽象類更高的抽象,它是一個完全抽象的類,即抽象方法的集合。接口中所有的方法不能有具體的實現,也就是說,接口中的方法必須都是抽象方法。而抽象類既可以有抽象方法也可以有普通方法。
接口使用關鍵字interface來聲明,語法格式如下:[ ] 裏面的內容代表可有可無
[public] interface 接口名稱 [extends 其他的類名] {
[public] [static] [final] 數據類型 成員名稱 = 常量值;
[public] [static] [abstract] 返回值 抽象方法名 (參數列表)
}
接口中的方法是不能實現的,只能由實現接口的類來實現。一個類可以通過關鍵字implements來實現。如果實現類中沒有實現接口中的所有抽象方法,那麼該類必須聲明爲抽象類。下面是接口聲明的一個簡單例子。
聲明一個含有面積和體積抽象方法的接口,並寫一個長方形類實現接口,在測試類中測試一下長方形面積和周長:
interface Shape{
public void area(); //計算面積
public void perimeter(); //計算周長
}
class Rectangle implements Shape{
private double length;
private double width;
public Rectangle( ){ } //空的構造方法
public Rectangle(double length2,double width2 ){ //可傳入長和寬參數的構造方法
this.length = length2;
this.width = width2;
}
public void setLength(double length1){
this.length = length1;
}
public double getLength(){
return length;
}
public void setWidth(double width1){
this.width= width1;
}
public double getWidth(){
return width;
}
public void area(){
System.out.println("該長方形的面積是:" + length*width );
}
public void perimeter(){
double a = 2*(length+width);
System.out.println("該長方形的周長是:" + a );
}
}
public class Count{
public static void main(String[] args){
Rectangle rt = new Rectangle(); //用無參構造函數實例化對象
rt.setLength(2.0);
rt.setWidth(4.0);
rt.area();
rt.perimeter();
Rectangle rt2 = new Rectangle(3.0,5.0); //用有參構造函數實例化一個新的對象,此對象通過含參構造函數賦值,可以
// 不用set賦值
rt2.area();
rt2.perimeter();
}
}
三.作業
人 :用筷子吃飯 ,工作是敲代碼 ,在牀上睡覺
貓:直接啃食物 ,工作是逮老鼠,在地面睡覺
寫一個具有eat(),work(),sleep()抽象方法的抽象類,並分別寫People,Cat類繼承該抽象類並實現抽象方法,用Test類輸出人和貓的具體特性。