服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java编程思想读书笔记(第5-7章)二


  第6章  重复运用classes
  
  一.继承(inheritance)
  
  1.  在derived class中overriding某个函数时,只能覆写base class中的接口,即base class中的public或protected或friendly函数。如果试图overriding一个private函数,虽然编译通过,但实际上你只是在derived class中添加了一个函数。如
  
  class cleanser{
  private void prt(){//(b)
  java/lang/system.java.html" target="_blank">system.out.println("cleanser.prt()");
  }
  }
  public class explicitstatic extends cleanser{
  public void prt(){
  java/lang/system.java.html" target="_blank">system.out.println("explicitstatic.prt()");
  }
  public static void main(java/lang/string.java.html" target="_blank">string[] args){
  cleanser x = new explicitstatic();
  x.prt();//(a)
  }
  }
  
  因为cleanser中的prt()是private,所以不能在其derived class中被覆写。explicitstatic中的prt()只是explicitstatic中的一个函数,所以当试图在(a)处通过多态来调用prt()时,会发生错误。如果把(b)处的private去掉,则结果为
  
  explicitstatic.prt()
  
  2.  super的使用
  
  1)通过关键字super可以调用当前class的superclass(父类)。
  例6.1.1.1
  
  class base{
  base(){java/lang/system.java.html" target="_blank">system.out.println("base()");}
  public void scrub() { java/lang/system.java.html" target="_blank">system.out.println(" base.scrub()"); }
  }
  class cleanser extends base{
  private java/lang/string.java.html" target="_blank">string s = new java/lang/string.java.html" target="_blank">string("cleanser");
  public void append(java/lang/string.java.html" target="_blank">string a) { s+=a; }
  public void dilute() { append(" dilute()"); }
  public void apply() { append(" apply()"); }
  public void scrub() { append(" scrub()"); }
  public void print() { java/lang/system.java.html" target="_blank">system.out.println(s); }
  cleanser(){
  java/lang/system.java.html" target="_blank">system.out.println("cleanser(): " + s);
  }
  public static void teststatic(){
  java/lang/system.java.html" target="_blank">system.out.println("teststatic()");
  }
  public static void main(java/lang/string.java.html" target="_blank">string[] args){
  cleanser x = new cleanser();
  x.dilute(); x.apply(); x.scrub(); x.print();
  }
  }
  public class explicitstatic extends cleanser{
  explicitstatic(){
  java/lang/system.java.html" target="_blank">system.out.println("explicitstatic()");
  }
  public void scrub(){
  append(" detergen.scrub()");
  super.teststatic();
  super.scrub();//调用的是cleanser.scrub()
  }
  public void foam() { append(" foam()"); }
  public static void main(java/lang/string.java.html" target="_blank">string[] args){
  explicitstatic x = new explicitstatic();
  x.dilute(); x.apply(); x.scrub(); x.foam();
  x.print(); java/lang/system.java.html" target="_blank">system.out.println("test base class:");
  cleanser.main(args);
  teststatic();
  }
  }
  
  运行结果:
  base()
  cleanser(): cleanser
  explicitstatic()
  teststatic()
  cleanser dilute() apply() detergen.scrub() scrub() foam()
  test base class:
  base()
  cleanser(): cleanser
  cleanser dilute() apply() scrub()
  teststatic()
  2)通过super来调用superclass中的成员时,调用的是最近成员。
  例6.1.1.2
  
  class base{
  protected java/lang/string.java.html" target="_blank">string bases = "base";//(a)
  //private string bases = "base";
  base(){java/lang/system.java.html" target="_blank">system.out.println("base()");}
  }
  class cleanser extends base{
  protected java/lang/string.java.html" target="_blank">string bases = "cleanser";//(b)
  public java/lang/string.java.html" target="_blank">string s = new java/lang/string.java.html" target="_blank">string("cleanser");
  cleanser(){
  java/lang/system.java.html" target="_blank">system.out.println("cleanser(): " + s);
  }
  cleanser(java/lang/string.java.html" target="_blank">string a){
  java/lang/system.java.html" target="_blank">system.out.println("cleanser(" + a + "): s = " + s );
  }
  }
  public class explicitstatic extends cleanser{
  java/lang/string.java.html" target="_blank">string s2 = s;
  java/lang/string.java.html" target="_blank">string bases = super.bases; //(c)
  explicitstatic(){
  super("explicitstatic");
  java/lang/system.java.html" target="_blank">system.out.println("explicitstatic():s2 = " + s2 + ", bases = "
  + bases + "super.bases = " + super.bases);
  bases = "explicitstatic";
  java/lang/system.java.html" target="_blank">system.out.println("bases = " + bases + " , super.bases = " + super.bases);
  }
  public static void main(java/lang/string.java.html" target="_blank">string[] args){
  explicitstatic x = new explicitstatic();
  }
  }
  
  结果1:
  base()
  cleanser(explicitstatic): s = cleanser
  explicitstatic():s2 = cleanser, bases = cleanser,super.bases = cleanser
  bases = explicitstatic , super.bases = cleanser
  
  在上面例子中,在三个class中都存在string bases实例。在explicitstatic中如果直接调用bases,则实际调用的是当前类explicitstatic中的bases(即(c)处的成员);如果通过super.bases来调用bases,则调用的是离当前类explicitstatic最近的bases成员,即cleanser class中的bases实例(即(b)处),产生的结果如结果1所示。如果把(b)处语句注释掉,则将调用base class中的bases,结果如结果2所示。
  
  结果2:
  base()
  cleanser(explicitstatic): s = cleanser
  explicitstatic():s2 = cleanser, bases = base,super.bases = base
  bases = explicitstatic , super.bases = base
  
  3.  base class的初始化
  
  2.1  当你产生derived class对象时,其中会包含base class子对象(subobject)。这个子对象就和你另外产生的base class对象一模一样。
  
  2.2  通过super()可调用base class的构造函数,但必须放在构造函数的第一行,并且只能在构造函数中运用。
  
  2.3  初始化顺序为:
  
  1)  加载代码(.class文件)
  
  2)  初始化class的静态成员,初始化顺序了“从里到外”,即从base class开始。
  
  3)  在derived class的构造函数中调用base class的构造函数。
  
  如果在derived class的构造函数中没有通过super()显式调用调用base class的构造函数,编译器会调用bass class的default构造函数并自动生成相应的调用语句,从而产生一个base class实例。如果在derived class的构造函数中通过super()显示调用了父类的构造函数,则调用所指定的构造函数。调用构造函数的调用顺序是“从里到外”。
  
  4)  调用derived class的构造函数。
  
  **:当base class没有default构造函数时,必须在derived class的构造函数中通过super显示调用base class的构造函数。
  
  例:下面代码的初始化过程为:
  
  1)  装载explicitstatic的代码(装载explicitstatic.class文件)。
  
  2)  发现explicitstatic有关键字extends,装载explicitstatic的base class的代码(装载cleanser.class文件)。
  
  3)  发现cleanser有关键字extends,装载cleanser的base class的代码(装载base.class文件)。
  
  4)  初始化base class中的静态成员。
  
  5)  初始化cleanser class中的静态成员。
  
  6)  初始化explicitstatic class中的静态成员。
  
  如果把(c)处的代码注释掉,那么初始化工作到此就结束了。
  
  7)  为explicitstatic对象分配存储空间,并把存储空间初始化为0。
  
  8)  在explicitstatic class的构造中调用super("explicitstatic")(在explicitstatic class的构造函数中显式调用父类的构造函数),试图产生一个cleanser class实例。
  
  9)  为cleanser对象分配存储空间,并把存储空间初始化为0。
  
  10)  由于cleanser class又是继承自base class,

扫描关注微信公众号