在看多型章節時發現多型和模糊化寫法、過載有相似之處,故決定開頭先複習,再介紹多型。
先複習模糊化寫法,在兩個類別是繼承關係時,我們可以使用模糊化寫法宣告物件,例如父類別是人類 Human,其中一個子類別是騎士 Kinght,我們宣告藍斯洛特是騎士時,可以寫作
Kinght lancelot = new Kinght();// 明確宣告藍斯洛特為一個騎士,口語說法:騎士藍斯洛特是一個騎士。
;可以寫作
Human lancelot = new Kinght();// 模糊宣告藍斯洛特為一個騎士,口語說法:人類藍斯洛特是一個騎士。
,上面這一行就是模糊化寫法,等號左邊只說了藍斯洛是人類,右邊才宣告了他是騎士;除此之外還可以寫作
var lancelot = new Kinght();
。無論上面哪一種寫法所產生出來的物件,都可以使用子類別中的方法,只是模糊寫法的物件在使用子類別的方法時,該物件必須強制轉型。
再來是過載特性的複習,在一個類別中,有複數個成員方法的名稱相同,但其需要的參數屬性或數量的不同,JAVA 可以自動依所傳的參數判斷要使用哪一個方法,這個特性稱之為過載。
JAVA 多型正是用到了模糊化寫法,而且擁有過載的特性。
宣告一個父類別,父類別中擁有它自己的方法,然後其子類別中也有同名的方法,覆寫掉父類別中的同名方法;在主程式中定義的方法指定丟入參數為父類別的物件,但實際上你可以丟入任何有繼承該父類別的子類別所產生的物件,這就是模糊化;而 JAVA 會自動使用該物件在子類別中的同名方法,這就是過載。以下是 Elton 教我多型概念時的範例。
父類別:Shape 形狀,包含了一個它自己的方法 area 面積;
public class Shape {
public double area() {
return 0;
}
}
子類別:Circle 圓形,包含了和父類別同名的方法 area 面積;
public class Circle extends Shape {
int r;
double pi = 3.1415926;
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
public double getPi() {
return pi;
}
public void setPi(double pi) {
this.pi = pi;
}
public double area() {
return pi*r*r;
}
}
子類別:Rectangle 矩形,包含了和父類別同名的方法 area 面積;
public class Rectangle extends Shape {
int length;
int width;
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public double area() {
return length * width;
}
}
主程式:裡面示範了方法的過載和多型兩種方式,註解應該算詳細,所以這裡不再說明。
public class Main {
// 以下是方法的多載(overloading),方法名稱相同,會依傳入的參數型別或數量不同而區別使用哪一方法。
// 萬一今天有多個不同的形狀,例如三角形,梯形,六角形等。下方就要為特定的形狀再多加宣告多組的面積方法,有些繁瑣。
public static double calArea(Circle cir) {
return cir.area();
}
public static double calArea(Rectangle rec) {
return rec.area();
}
// 那麼為了有更簡潔的方式,我們可以使用到多型的觀念。只宣告一組面積方法來算所有形狀的面積。
// 設定承接物件為父類別,模糊化所承接之物。
public static double calAreaBetter(Shape sha) {
return sha.area();
}
public static void main(String[] args) {
Circle cir1 = new Circle();
cir1.setR(12);
Rectangle rec1 = new Rectangle();
rec1.setLength(5);
rec1.setWidth(10);
double cirArea = calArea(cir1);
double recArea = calArea(rec1);
System.out.println("this is an area of circle by cir method:" + cirArea);
System.out.println("this is an area of rectangle by rec method:" + recArea);
cirArea = calAreaBetter(cir1);
recArea = calAreaBetter(rec1);
System.out.println("this is an area of circle by better method:" + cirArea);
System.out.println("this is an area of rectangle by better method:" + recArea);
}
}
結果:不管是用方法的過載或是多型的概念,都得到同樣的面積值。
this is an area of circle by cir method:452.38933440000005
this is an area of rectangle by rec method:50.0
this is an area of circle by better method:452.38933440000005
this is an area of rectangle by better method:50.0
Process finished with exit code 0
這個範例中的父類別是一般的類別,但我買的書,其範例是用抽象類別當父類別,或是用介面讓不同的類別實作,來完成多型的目的,其使用是自由自在的,下一篇會再練習一次多型,應該也是最後一篇物件導向的概念文章了,之後會練習如何使用套件與檔案處理。
沒有留言:
張貼留言