學習了Java和C++之後,由於長期不使用C++,而java的基礎知識掌握不牢,現在已經搞不清java多態了。現在先來談談java多態,稍後有時間再更新C++的多態,並進行比較~
一. Java的多態
首先什麼是Java的多態?
多態是同一個行為具有多個不同表現形式或形態的能力。多態就是同一個接口,使用不同的實例而執行不同操作。
Java中多態的實現方式:接口實現,繼承父類進行方法重寫,同一個類中進行方法重載。
1. 方法的重載
方法的重載是指在一個類中,出現多個方法名相同,但參數個數或參數類型不同的方法,則稱為方法的重載。Java在執行具有重載關系的方法時,將根據調用參數的個數和類型區分具體執行的是哪個方法。
【例1】 定義一個名稱為Calculate的類,在該類中定義兩個名稱為getArea()的方法(參數個數不同)和兩個名稱為draw()的方法(參數類型不同)。
package test;
public class Calculate {
final float PI = 3.14159f;
public float getArea(float r){
float area = PI * r *r;
return area;
}
public float getArea(float l,float w){
float area = 1 * w;
return area;
}
public void draw(int num){
System.out.println("畫"+num+"個任意形狀的圖形");
}
public void draw(String shape){
System.out.println("畫一個"+shape);
}
public static void main(String[] args){
Calculate calculate = new Calculate();
float l = 20;
float w = 30;
float areaRectangle = calculate.getArea(l,w);
System.out.println("求長為"+l+"寬為"+w+"的矩形的面積是:"+areaRectangle);
float r = 7;
float areaCirc = calculate.getArea(r);
System.out.println("求半徑為"+r+"的圓的面積是:"+areaCirc);
int num = 7;
calculate.draw(num);
calculate.draw("三角形");
}
}
執行結果如下圖所示:
重載的方法之間並不一定必須有聯系,但是為了提高程序的可讀性,一般只重載功能相似的方法。
注意:在方法重載時,方法的返回值類型不能作為區分方法重載的標志。
2.方法的覆蓋(重寫)
當子類繼承父類中所有可能被子類訪問的成員方法時,如果子類的方法名與父類的方法名相同,那麼子類就不能繼承父類的方法,此時,稱子類的方法覆蓋了父類的方法。覆蓋體現了子類補充或者改變父類方法的能力,通過覆蓋,可以使一個方法在不同子類中表現出不同的行為。
【例2】定義動物類Animal及它們的子類,然後在Zoo類中分別創建各個子類對象,並調用子類覆蓋父類的cry()方法。
(1)創建一個名稱為Animal的類,在該類中聲明一個成員方法cry():
package example_2;
public class Animal {
public Animal() {
}
public void cry(){
System.out.println("動物發出叫聲!");
}
}
(2)創建一個Animal類的子類Dog類,在該類中覆蓋父類的成員方法cry():
package example_2;
public class Dog extends Animal {
public Dog() {
}
public void cry(){
System.out.println("狗發出“汪汪.....”聲!");
}
}
(3)再創建一個Animal類的子類Cat類,在該類中覆蓋了父類的成員方法cry():
package example_2;
public class Cat extends Animal{
public Cat() {
}
public void cry(){
System.out.println("貓發出“喵喵....”聲!");
}
}
(4)再創建一個Animal類的子類Cattle類,在該類中不定義任何方法:
1 package example_2; 2 3 public class Cattle extends Animal { 4 5 }View Code
(5)創建Zoo類,在該類的main()方法中分別創建子類Dog,Cat和Cattle的對象並調用它們的cry()成員方法:
package example_2;
public class Zoo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Dog dog = new Dog();
System.out.println("執行dog.cry();語句時的輸出結果:");
dog.cry();
Cat cat = new Cat();
System.out.println("執行cat.cry();語句時的輸出結果:");
cat.cry();
Cattle cattle = new Cattle();
System.out.println("執行cattle.cry();語句時的輸出結果:");
cattle.cry();
}
}
運行結果如下圖所示:
從上面的運行結果中可以看出,由於Dog類和Cat類都重寫了父類的方法cry(),所以執行的是子類中的cry()方法,但是Cattle類沒有重寫父類的方法,所以執行的是父類中的cry()方法。事實上,在Zoo類中,如下寫法更能體現多態性:
package example_2;
public class Zoo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal animal;
animal = new Dog();
System.out.println("執行animal.cry();語句時的輸出結果:");
animal.cry();
animal = new Cat();
System.out.println("執行animal.cry();語句時的輸出結果:");
animal.cry();
animal = new Cattle();
System.out.println("執行animal.cry();語句時的輸出結果:");
animal.cry();
}
}
在進行方法覆蓋時,需要注意一下幾點:
3.接口實現