多態:可以理解爲事物存在的多種體現形態,比如說人:男人、女人;動物:貓,狗。
多態:
多種形態。
這裏要重點講的就是對象的多態性。
狗 x = new 狗();
動物 y = new 狗();//對象的多態性,狗對象即是狗類型,又是動物形態。
必須要明確一點:狗是動物中的一種。
意味着狗是需要繼承動物的纔可以這樣指向。
多態性:在程序中的體現。
就是:父類或者接口的引用指向自己的子類對象。
好處:提高了代碼的擴展性。
弊端:前期建立父類的引用雖然可以接收後期所有該類的子類對象。
但是隻能使用父類中的功能,不能使用子類中的特有功能,
因爲前期的程序無法知道後期的子類的特有內容的。
但是前期的程序可以使用子類覆蓋了父類的方法的內容。
前提:
1,必須存在着繼承關係。
2,通常要有覆蓋操作。
*/
abstract class Animal
{
abstract void eat();
}
class Dog extends Animal
{
public void eat()
{
System.out.println("啃骨頭");
}
public void lookHome()
{
System.out.println("看家");
}
}
class Cat extends Animal
{
public void eat()
{
System.out.println("喫魚");
}
public void catchMouse()
{
System.out.println("抓老鼠");
}
}
class Pig extends Animal
{
public void eat()
{
System.out.println("飼料");
}
public void gongDi()
{
System.out.println("拱地");
}
}
class DuoTaiDemo
{
public static void main(String[] args)
{
Animal a = new Dog();//子類對象的類型提升。向上轉型[類似於基本類型的類型提升,只不過這裏是引用類型數據,]。
a.eat();
Dog d = (Dog)a;//向下轉型。 轉成子類型。 d.eat();
d.lookHome();
可以看出,向上轉型爲自動提升,向下轉型必須強制
}
public static void function(Ainimal a){
a.eat();
if (a instanceof Cat){ {
Cat c=(Cat)a;
c.catchMouse();
}
else if (a instanceof Dog)
{
Dog d=(Dog)a;
d.lookHome();
}
}//the above method showed one point should be careful in using the 多態
}
多態中函數成員的特點:
在編譯時期:參閱引用類型變量所屬的類中是否有調用的方法,如果有,編譯通過,如果沒有編譯失敗。
在運行時期:參閱對象所屬的類中是否有調用的方法:------編譯看引用,運行得看對象
總的來說在多態中,成員函數在多態調用時,編譯看左邊,運行看右邊。
成員變量的特點,無論編譯和運行,都參考左邊(引用型變量所屬的類)。
多態的出現在成員調用上的特點:
1,成員變量
編譯時期:參考的是引用型變量所屬的類中是否有調用的成員變量,如果有,編譯通過,如果沒有編譯失敗。
運行時期:調用的也是引用型變量所屬類中的成員變量。
簡單說:編譯和運行都看等號的左邊。
其實這種情況不多見。
2,成員函數。
編譯時期;參考的是引用型變量所屬的類中是否有調用的方法。有,編譯通過,沒有編譯失敗。
運行時期:參考的是對象所屬的類中是否有調用的方法,如果有運行子類自己的方法,如果沒有就父類的方法。
簡答說:編譯時期看左邊,運行時期看右邊。
因爲函數有一個覆蓋的特性。
非靜態方法需要和當期運行的對象進行動態綁定,哪個對象調用了這個方法,這個方法就所屬於哪個對象。
就會運行哪個對象的中的方法。
3,靜態函數。
編譯時期:參考的是引用型變量所屬的類中是否該方法。
運行時期:參考的也是引用型變量所屬的類中的方法。
簡單說:編譯和運行都看左邊。所謂的看左看右是指根據左邊或右邊的屬性或者方法來完成調用
因爲靜態方法是不所屬於對象的,是所屬於類的,
它會類加載的時候,靜態的綁定到所屬的類上。
*/
class Fu
{
int num = 4;
public void show()// 因爲覆蓋的特性,
{
System.out.println("fu show run");
}
public static void staticMethod()
{
System.out.println("fu static method run");
}
}
class Zi extends Fu
{
int num = 5;
public void show()// 因爲覆蓋的特性,
{
System.out.println("zi show run");
}
public static void staticMethod()
{
System.out.println("zi static method run");
}
}
class DuoTaiTest
{
public static void main(String[] args)
{
Fu f = new Zi();
// System.out.println(f.num);//4
// f.show();//zi show run 因爲函數覆蓋的特性,運行的子類對象在調用show方法,
//覆蓋了父類中的方法,運行的是子類自己的show方法。
f.staticMethod();
Zi z = new Zi();
z.staticMethod();
Fu.staticMethod();
Zi.staticMethod();
}
}