構造器內部多型方法的行為
阿新 • • 發佈:2018-11-25
如果在超類的構建器中呼叫了子類覆蓋過的方法,則編譯器預設會呼叫在超類構建的過程中呼叫已經被子類覆蓋過的方法,而不是超類中的原始方法。這種錯誤很難從邏輯上進行排查,所以一定要格外小心!以下是例子:
class Glyph { void draw() { System.out.println("Glyph.draw()");} Glyph() { System.out.println("Glyph () before draw()"); draw(); System.out.println("Glyph () after draw()"); } } class RoundGlyph extends Glyph{ private int radius = 1; RoundGlyph(int r){ radius = r; System.out.println("RoundGlyph.RoundGlyph().radius = " + radius); } void draw(){ System.out.println("RoundGlyph.draw().radius = " + radius); } } public class PolyConstructors { public static void main(String args[]){ new RoundGlyph(5); } } /*output Glyph () before draw() RoundGlyph.draw().radius = 0 Glyph () after draw() RoundGlyph.RoundGlyph().radius = 5 */
我們本來應該得到的draw()方法應該是超類未被覆蓋的draw()方法,然而編譯器呼叫的卻是子類中的draw()方法。而此時子類構建器還未初始化,但是在例項已經給物件的儲存空間初始化成二進位制的0,所以看到radius為0而不是1 。