子類的對象可以向上造型為父類的類型。即父類引用子類對象,這種方式被稱為向上造型。
在日常生活中,我們都扮演着不一樣的角色。我們有可能是老師,有可能是學生,有可能是……, 但是我們都有共同的屬性,例如:名字、性別、年齡……,但是在該基礎上,不同身份的人也有着屬於自己的不同的特點。我們通常描述他人的時候會說,這個人是老師,這個認識學生,這個人是個程序員……。實際上“這個人是……”這種說法就是向上造型。
直接上代碼:
/** * Person類,父類,用於描述人的共有的屬性 * */ class Person { String name; //例子屬性,表示一個人的名字 public Person() { name = "Person"; //初始化一個值 System.out.println("I'm Person!"); } //定義sayHi()方法,默認輸出HelloWorld protected void sayHi() { System.out.println("HelloWorld!"); } }
上面的這個Person類就代表了,我們的部分屬性(name),和共有的行為(sayHi())。
再看看子類:
/** * Student 類, 繼承了Person類 * */ class Student extends Person { String className; //班級名 public Student() { name="haydn"; //為父類里的name重新賦值 className = "菜鳥營一班"; //為className賦值 System.out.println("I'm Student"); } //這里重寫了父類的sayHi方法 protected void sayHi() { System.out.println("stuName=" + name); System.out.println("stuClassName=" + className); } public void stuTalk() { System.out.println("I like Java"); } }
注意:子類里有一個訪問權限、返回值類型、方法名和父類一樣的方法,這樣就代表重寫了父類。稍后我們來詳細說明,先看測試。
代碼如下:
public static void main(String[] args) { Person pstu = new Student(); System.out.println("name="+pstu.name); pstu.sayHi(); }
輸出結果:
I’m Person! I’m Student name=haydn stuName=haydn stuClassName=菜鳥營一班
執行流程:
在new Student()的時候由於繼承關系,先后分別先打印了I’m Person!和I’m Student。執行Person構造時name被賦值為”person”
執行Student構造時name被重新賦值為”haydn”。所以打印了name=haydn。由於子類重寫了父類的方法,所以並沒有打印HelloWorld,而是打印了stuClassName=菜鳥營一班。證明產生了向上造型。
注意:父類不能引用子類中的屬性或方法。只能由子類重寫父類中的方法或屬性。
代碼如下:
public static void main(String[] args) { Person pstu = new Student(); System.out.println("name="+pstu.name); pstu.sayHi(); //編譯不通過,父類不能直接調用子類屬性和方法 //pstu.className; //pstu.stuTalk(); }
是重寫時對訪問權限和返回值的說明:
在Java中向上造型的父類被認為是“大”的,所以在向上造型的時候重寫父類方法,方法的訪問權限一定要大於等於父類。返回值要和父類相同
例子代碼:
//編譯通過,訪問權限和父類一致為protected protected void sayHi() { name="rose"; System.out.println(title); } //編譯通過,訪問權限大於父類 public void sayHi() { name="rose"; System.out.println(title); } //編譯不通過,權限小於父類 private void sayHi() { name="rose"; System.out.println(title); } //編譯不通過,數據類型不一致 protected int sayHi() { return 1; }
總結:向上造型即允許一種類型有不同的實現,要注意重寫父類方法返回值和訪問權限的問題。要注意父類是不可以訪問子類對象的屬性或方法的。