Java 继承与初始化、“覆盖”私有方法

来源:互联网 发布:js消除数组重复元素 编辑:程序博客网 时间:2024/04/29 17:50

参考Java编程思想

主要是为了在调试过程中发现初始化的顺序,及程序调用的顺序,加深印象

class Insect {  private int i = 9;  protected int j;  Insect() {    System.out.println("i = " + i + ", j = " + j);    j = 39;  }  private static int x1 =    printInit("static Insect.x1 initialized");  static int printInit(String s) {    System.out.println(s);    return 47;  }}public class Beetle extends Insect {  private int k = printInit("Beetle.k initialized");  public Beetle() {    System.out.println("k = " + k);    System.out.println("j = " + j);  }  private static int x2 =    printInit("static Beetle.x2 initialized");  public static void main(String[] args) {    System.out.println("Beetle constructor");    Beetle b = new Beetle();  }} /* Output:static Insect.x1 initializedstatic Beetle.x2 initializedBeetle constructori = 9, j = 0Beetle.k initializedk = 47j = 39*///:~

期望输出是public(),但由于private方法被自动认为final方法,而起对导出类是屏蔽的

public class PrivateOverride {  private void f() { System.out.println("private f()"); }  public static void main(String[] args) {    PrivateOverride po = new Derived();    po.f();  }}class Derived extends PrivateOverride {  public void f() { System.out.println("public f()"); }} /* Output:private f()*///:~

域与静态方法

本例中Super.field和Sub.field分配了不同的空间。Sub实际上包含两个field域:它自己和从Super处得到的

class Super {  public int field = 0;  public int getField() { return field; }}class Sub extends Super {  public int field = 1;  public int getField() { return field; }  public int getSuperField() { return super.field; }}public class FieldAccess {  public static void main(String[] args) {    Super sup = new Sub(); // Upcast    System.out.println("sup.field = " + sup.field +      ", sup.getField() = " + sup.getField());    Sub sub = new Sub();    System.out.println("sub.field = " +      sub.field + ", sub.getField() = " +      sub.getField() +      ", sub.getSuperField() = " +      sub.getSuperField());  }} /* Output:sup.field = 0, sup.getField() = 1sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0*///:~

如果某个方法是静态的,它的行为就不具有多态性

class StaticSuper {  public static String staticGet() {    return "Base staticGet()";  }  public String dynamicGet() {    return "Base dynamicGet()";  }}class StaticSub extends StaticSuper {  public static String staticGet() {    return "Derived staticGet()";  }  public String dynamicGet() {    return "Derived dynamicGet()";  }}public class StaticPolymorphism {  public static void main(String[] args) {    StaticSuper sup = new StaticSub(); // Upcast    System.out.println(sup.staticGet());    System.out.println(sup.dynamicGet());  }} /* Output:Base staticGet()Derived dynamicGet()*///:~

初始化过程:

1.在其他任何事物发生之前,将分配给对象的存储空间初始化为二进制的0

2.如下调用基类构造器。此时调用被覆盖后的draw()方法(要在调用RoundGlyph构造器之前调用),由于步骤1,发现radius 的值为0

3.按声明的顺序调用成员的初始化方法

4.调用导出类的构造器主体

在构造器内唯一能够安全调用的方法是基类中的final方法(也适用于private方法,它自动属于final方法),这些方法不能被覆盖。

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 */// :~

用继承表达行为间的差异,并用字段表达状态上的变化

class Actor {  public void act() {}}class HappyActor extends Actor {  public void act() { print("HappyActor"); }}class SadActor extends Actor {  public void act() { print("SadActor"); }}class Stage {  private Actor actor = new HappyActor();  public void change() { actor = new SadActor(); }  public void performPlay() { actor.act(); }}public class Transmogrify {  public static void main(String[] args) {    Stage stage = new Stage();    stage.performPlay();    stage.change();    stage.performPlay();  }} /* Output:HappyActorSadActor*///:~


原创粉丝点击