歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java 多態——與C++的比較

Java 多態——與C++的比較

日期:2017/3/1 9:07:25   编辑:Linux編程

學習了Java和C++之後,由於長期不使用C++,而java的基礎知識掌握不牢,現在已經搞不清java多態了。現在先來談談java多態,稍後有時間再更新C++的多態,並進行比較~

一. Java的多態

首先什麼是Java的多態?

多態是同一個行為具有多個不同表現形式或形態的能力。多態就是同一個接口,使用不同的實例而執行不同操作。

  • 實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
  • 多態的作用:消除類型之間的耦合關系。

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();

}

}

在進行方法覆蓋時,需要注意一下幾點:

  • 子類不能覆蓋父類中聲明為final或者static的方法。
  • 子類必須覆蓋父類中聲明為abstract的方法,或者子類也將該方法聲明為abstract。
  • 子類覆蓋父類中的同名方法時,子類中方法的聲明也必須和父類中被覆蓋的方法的聲明一樣。

3.接口實現

Copyright © Linux教程網 All Rights Reserved