1. 程式人生 > >Java 動態綁定/多態

Java 動態綁定/多態

技術 由於 float http println mage 同名 [] point


class Point { int x = 0, y = 0;    //父類成員Var public void move(int x,int y){ this.x += x; this.y += y; } public int getX(){ return x; } public int getY(){ return y; } } class RealPoint extends Point { float x = 0.0f ,y = 0.0f;      //子類成員Var , 與父類同名,隱藏父類成員Var, 包括訪問權限、類型 均以子類為準。
public void move(float x, float y){  //與繼承的父類方法的重寫(Override)構成重載。 this.x += x;            //this指向本身的引用,this.x 代表自身類的成員Var this.y += y; } public void move(int x,int y){    //對父類方法的重寫,調用自身類的重載方法(Overload)參數個數和類型不同,其余相同。 move((float)x, (float)y); } public int getX() {
return (int)Math.floor(x);    //Math.floor() 向下取整,直接截取小數點後小數部分。 } public int getY() { return (int)Math.floor(y); } } public class Polymorphism { public static void main(String []args) { RealPoint rp = new RealPoint();    //創建子類對象,子類引用指向子類對象 Point p = rp;              //父類引用類型,指向子類對象(p 和 rp指向內存同一塊區域)Casting 對象轉型 rp.move(
1.71828f,4.14159f);      //調用子類定義的第一個方法 p.move(1,-1);               //調用子類定義的第二個方法,其真正實現,由第一個方法實現。  show(p.x, p.y);              //顯示父類成員Var, 非靜態成員變量在類加載的第二階段已經加載好了,不會有動態綁定。 show(rp.x, rp.y);              //顯示子類成員Var show(p.getX(),p.getY());        //調用子類getX() getY(),子類方法返回子類成員Var,成員方法(有繼承,有父類引用指向子類對象,有重寫)會實現動態綁定,
                            //調用實際指向的對象的方法,即調用RealPoint中的getX(),getY();
show(rp.getX(),rp.getY());      //調用子類成員方法 }
public static void show(int x, int y){ System.out.println("(" + x + "," + y + ")"); } public static void show(float x ,float y) { System.out.println("(" + x + "," + y + ")"); } }
技術分享圖片
(0,0)
(2.7182798,3.14159)
(2,3)
(2,3)
View Code

源程序如上圖,動態綁定(多態) 是針對的非static 、非final的成員方法,隱藏針對的是成員變量和static 方法。(針對且只針對)

只有Override (重寫) 才會進行動態綁定,隱藏(即子類聲明和父類同名同類型的成員變量和static 方法,則子類實例化對象通過對象名調用成員Variable 和 static 方法,子類的相應將父類隱藏,只會顯示子類的成員Var 和 static 方法)。隱藏不會進行動態綁定。

技術分享圖片

內存布局如圖所示,

1、p和rp指向同一子類對象。

2、子類繼承父類,即子類對象包含父類對象。

3、動態綁定:原本父類對象的move()指針指向父類Point()的方法,由於有繼承、有父類引用指向子類對象、有重寫,Java會執行動態綁定機制,使得源代碼中p.move(1,-1)調用的為子類的move()方法。 move()由黑線改成藍色指向的move()方法。

4、父類引用指向子類對象,只能調用子類的方法,不能得到子類的成員變量(成員Var 無動態綁定,且Casting限定了父類引用只能使用父類Obj內部的方法和變量)。即p.getX() 調用的為子類方法。 p.x 不會得到子類的成員Var , 這也就是結果第一、二的出現的原因。

5、但是父類引用指向子類對象,調用子類方法,子類方法可以對子類成員變量進行操縱,近似於(但不等同於)父類引用可以得到子類成員Var(但並非直接,而是通過子類方法,子類方法向外提供修改子類成員Var的接口). p.getX() p.getY() 而 getX() getY()返回的為子類自身成員Var。程序結果第三、四行出現的結果。

Java 動態綁定/多態