java笔记一

java 代码
  1. //: notes about thinking in java    
  2. //c07:Sandwich.java   
  3. // Order of constructor calls.   
  4. // From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002   
  5. // www.BruceEckel.com. See copyright notice in CopyRight.txt.   
  6. package c07;   
  7. import com.bruceeckel.simpletest.*;   
  8.   
  9. class Meal {   
  10.   Meal() { System.out.println("Meal()"); }   
  11. }   
  12.   
  13. class Bread {   
  14.   Bread() { System.out.println("Bread()"); }   
  15. }   
  16.   
  17. class Cheese {   
  18.   Cheese() { System.out.println("Cheese()"); }   
  19. }   
  20.   
  21. class Lettuce {   
  22.   Lettuce() { System.out.println("Lettuce()"); }   
  23. }   
  24.   
  25. class Lunch extends Meal {   
  26.   Lunch() { System.out.println("Lunch()"); }   
  27. }   
  28.   
  29. class PortableLunch extends Lunch {   
  30.   PortableLunch() { System.out.println("PortableLunch()");}   
  31. }   
  32.   
  33. public class Sandwich extends PortableLunch {   
  34.   private static Test monitor = new Test();   
  35.   private Bread b = new Bread();   
  36.   private Cheese c = new Cheese();   
  37.   private Lettuce l = new Lettuce();   
  38.   public Sandwich() {   
  39.     System.out.println("Sandwich()");   
  40.   }   
  41.   public static void main(String[] args) {   
  42.     new Sandwich();   
  43.     monitor.expect(new String[] {   
  44.       "Meal()",   
  45.       "Lunch()",   
  46.       "PortableLunch()",   
  47.       "Bread()",   
  48.       "Cheese()",   
  49.       "Lettuce()",   
  50.       "Sandwich()"  
  51.     });   
  52.   }   
  53. ///:~   
  54. /*例子说明对象调用构造器要遵循以下顺序:  
  55. 1)调用基类构造器。这个步骤会不断反复递归下去,首先是构造这种层次结构的根,  
  56. 然后是下一层倒出类,等等,知道最底层的倒出类  
  57. 2)按声明顺序调用成员的初始化方法  
  58. 3)调用导出类构造器的主体*/  
  59.   

 

java 代码
  1. //:notes about thinking in java    
  2. //c07:PolyConstructors.java   
  3. // Constructors and polymorphism   
  4. // don't produce what you might expect.   
  5. // From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002   
  6. // www.BruceEckel.com. See copyright notice in CopyRight.txt.   
  7. import com.bruceeckel.simpletest.*;   
  8.   
  9. abstract class Glyph {   
  10.   abstract void draw();   
  11.   Glyph() {   
  12.     System.out.println("Glyph() before draw()");   
  13.     draw();   
  14.     System.out.println("Glyph() after draw()");   
  15.   }   
  16. }   
  17.   
  18. class RoundGlyph extends Glyph {   
  19.   private int radius = 1;   
  20.   RoundGlyph(int r) {   
  21.     radius = r;   
  22.     System.out.println(   
  23.       "RoundGlyph.RoundGlyph(), radius = " + radius);   
  24.   }   
  25.   void draw() {   
  26.     System.out.println(   
  27.       "RoundGlyph.draw(), radius = " + radius);   
  28.   }   
  29. }   
  30.   
  31. public class PolyConstructors {   
  32.   private static Test monitor = new Test();   
  33.   public static void main(String[] args) {   
  34.     new RoundGlyph(5);   
  35.     monitor.expect(new String[] {   
  36.       "Glyph() before draw()",   
  37.       "RoundGlyph.draw(), radius = 0",   
  38.       "Glyph() after draw()",   
  39.       "RoundGlyph.RoundGlyph(), radius = 5"  
  40.     });   
  41.   }   
  42. ///:~   
  43. /*在Glyph中,draw()方法是抽象的,这样设计是为了覆盖该方法。我们确实在RoundGlyph中强制覆盖  
  44. draw()。但是Glyph构造器会调用这个方法,结果导致了对RoundGlyph.draw()的调用,这看起来  
  45. 似乎是我们的目的。但是看到输出结果时我们会发现Glyph的构造起用draw()方法时,radius不是默认  
  46. 初始值1,而是0。这可能是导致在屏幕上只画了一个点,或者根本什么东西都没有。  
  47. 这一迷题的关键所在,初始化的实际过程是:  
  48. 1)在其他任何事务发生之前,将分配给对象的存储空间初始化成二进制的零  
  49. 2)如前所述那样调用构造器。此时,调用被覆盖后的draw()方法(要在调用RoundGlyph  
  50. 构造器之前调用),由于步骤1的缘故,我们此时会发现radius的值为0   
  51. 3)按照声明的顺序调用成员的初始化方法  
  52. 4)调用导出类的构造器主题*/  
  53.   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值