過載和多型的區別
過載和多型一直是不同的,對於剛學java的人來說會比較容易混淆。下面是小編為大家準備的,希望大家喜歡!
多型性也是面向物件方法的一個重要特性.多型性是指在在程式中出現的"重名"現象,即在一個程式中相同的名字可以表示不同的實現.
在JAVA中,多型性主要表現在如下兩個方面:
***1***方法過載.通常指在同一個類中,相同的方法名對應著不同的方法實現,但是方法的引數不同.
***2***成員覆蓋.通常指在不同類***父類和子類***中,允許有相同的變數名,但是資料型別不同;也允許有相同的方法名,但是對應的方法實現不同.
在過載的情況下,同一類中具有相同的名字的方法.如何選擇它的方法體呢?不能使用類名來區分,通常採用不同的方法形參表,區分過載要求形參在型別,個數和順序的不同,在定義過載方法時,應在方法的形參的型別,個數和順序有所不同,以便在選擇時能夠區別開來.
在覆蓋的情況下,同名的方法存在於不同的類中,在呼叫方法只要指明其方法所歸屬的類名就可以了.
例如
class Shape {
void draw****** {}
void erase****** {}
}
class Circle extends Shape {
void draw****** {
System.out.println***"Circle.draw******"***;
}
void erase****** {
System.out.println***"Circle.erase******"***; }
}
class Square extends Shape {
void draw****** {
System.out.println***"Square.draw******"***;
}
void erase****** {
System.out.println***"Square.erase******"***;
}
}
class Triangle extends Shape {
void draw****** {
System.out.println***"Triangle.draw******"***;
}
void erase****** {
System.out.println***"Triangle.erase******"***;
}
}
public class Test {
public static Shape randShape****** {
switch******int******Math.random****** * 3****** {
default:
case 0: return new Circle******;
case 1: return new Square******;
case 2: return new Triangle******;
} }
public static void main***String[] args*** {
Shape[] s = new Shape[9];
for***int i = 0; i < s.length; i++***
s[i] = randShape******;
for***int i = 0; i < s.length; i++***
s[i].draw******;
}
}
輸出結果
Triangle.draw******
Circle.draw******
Triangle.draw******
Triangle.draw******
Triangle.draw******
Square.draw******
Square.draw******
Triangle.draw******
Circle.draw******
Triangle.erase******
Circle.erase******
Triangle.erase******
Triangle.erase******
Triangle.erase******
Square.erase******
Square.erase******
Triangle.erase******
Circle.erase******
Press any key to continue...
又一次執行
Triangle.draw******
Triangle.draw******
Circle.draw******
Circle.draw******
Circle.draw******
Triangle.draw******
Triangle.draw******
Square.draw******
Circle.draw******
Triangle.erase******
Triangle.erase******
Circle.erase******
Circle.erase******
Circle.erase******
Triangle.erase******
Triangle.erase******
Square.erase******
Circle.erase******
Press any key to continue...
兩次執行結果不同的原因是其中的Math.random******這個類導致的,math.random******得到的數是0-1之間的隨機數.
寫到這裡,我突然想到了方法過載,那麼它和多型,覆蓋有什麼區別呢?到GOOGLE是搜素了一下,不少.
不過,最重要的一點區別是:通過方法過載進而實現物件的多型性.
方法過載是指功能相同的多個方法使用同一個方法名.同名的多個方法的引數要有所不同,即在引數型別,引數個數和引數順序上要有所區別,以便作為選擇某個方法的根據.通常只有功能相同的方法進行過載才有意義.
例如:計算兩個數之和的過載方法定義如下:
int add***int i,int j***
{retrun i+j;}
float add***float i,float j***
{retrun i+j;}
double add***double i,double j***
{retrun i+j;}
過載方法的選擇通常是在編譯時進行.系統根據不同的引數型別,個數或順序,尋找最佳匹配方法.方法型別不參與匹配.
下面是搜到的一些例子.
public class Base{
int a,b;
public Base***int x,int y***{
a = x;
b = y;
}
public int add******{
return ***a + b***;
}
public void add***int x,int y***{
int z;
z = x + y;
}
}
上面這段程式碼就是過載~~~他有三個特徵
1:方法名必須一樣 “add******“。
2:返回型別可以不一樣 就象是 ”int “和”void“.
3:引數可以不一樣 就是add****** 和add***int x,int y***這樣的。
public class Base{
int x,y;
public void add******{
int z;
z = x + y;
}
}
public class Child extends Base{
int x,y;
public void add******{
int z;
z = x + y;
}
public static void main***string [] args***{
Base b = new Child******;
b.add******;
}
}
下面這個例子就是重寫,他實現了多型~~
重寫的要求是,方法名必須一樣,返回型別必須一樣,傳入的引數必須一樣
在main函式中定義父類的物件,但是用子類去例項化他,這樣就可以通過父類的物件呼叫到子類的方法。
下面還有一個例題.
public class Parent {
public int addValue*** int a, int b*** {
int s;s = a+b;return s;
}
}
class Child extends Parent {
}
Which methods can be added into class Child?
a int addValue*** int a, int b ***{// do something...}
b public void addValue ******{// do something...}
c public int addValue*** int a ***{// do something...}
d public int addValue*** int a, int b ***throws MyException {//do something...}
答案為B.C
解釋1:
a是覆蓋,b ,c是過載
a的問題出在訪問許可權上,如果換成public也是可以的
d是異常的問題.
解釋2:
a的訪問許可權小於父類,所以錯誤,d是異常錯誤,b和c中的addValue方法和父類的方法引數不同,所以是過載.
解釋3:
在同一個類中方法成員的名稱相同,但引數的型別和個數不同,這稱為過載。
在存在繼承關係的兩個話,子類與父類的方法成員名稱相同、引數的型別和個數相同的話,子類的方法覆蓋父類的方法,這稱為覆蓋。