初始化与继承

对象的四种初始化方式:

  1、在定义对象的地方

  2、在类的构造其中

  3、在正要使用这些对象之前,也称为惰性初始化。

  4、使用实例(代码块)初始化

下面是这四种方法的具体使用:

 1 class Soap{
 2     private String s;
 3     public Soap(){
 4         System.out.println("soap()");
 5         s="constucted";
 6     }
 7     public String toString(){return s;}
 8 }
 9 public class Bath {
10     private String s1="Happy";     //The method 1.
11     private String s2,s3;
12     private Soap castille;
13     private int i;
14     public Bath(){
15         System.out.println("Inside Bath()");
16         s2="Joy";        //The method 2.
17         castille=new Soap();
18     }
19     {i=100;}    //The method 4.
20     public String toString(){
21         if(s3==null){s3="Jone";}        //The method 3.
22         return    "s1="+s1+"\n"+"s2="+s2+"\n"+"s3="+s3+"\n"+"i="+i+"\n"+"castille="+castille;    
23     }
24     public static void main(String[] args) {
25         Bath b=new Bath();
26         System.out.println(b);
27     }
28 }
29 //output:
30 Inside Bath()
31 soap()
32 s1=Happy
33 s2=Joy
34 s3=Jone
35 i=100
36 castille=constucted

基类的自动初始化:

 1 class Cleaner{
 2     private String s="cleaner";
 3     public Cleaner(){
 4         System.out.println("Cleaner Constructor.");
 5     }
 6     public void append(String str){s+=str;}
 7     public void dilute(){append("\tCleaner.dilute");}
 8     public String toString(){return s;}
 9 }
10 class Geli extends Cleaner{
11     public Geli(){
12         System.out.println("Geli Constructor.");
13     }
14     public void dilute(){
15         append("\tGeli.dilute");
16         super.dilute();
17     }
18 }
19 class Hair extends Geli{
20     public Hair(){
21         System.out.println("Hair Constructor.");
22     }
23     public void dilute(){
24         append("\tHair.dilute");
25         super.dilute();
26     }
27     public void ster(){
28         append("\nster()");
29     }
30 }
31 public class demo01 {
32     public static void main(String[] args) {
33         Cleaner c=new Hair();
34         c.dilute();
35         System.out.println(c);
36         //c.ster();    illegal
37     }
38 }
39 //output:
40 Cleaner Constructor.
41 Geli Constructor.
42 Hair Constructor.
43 cleaner    Hair.dilute    Geli.dilute    Cleaner.dilute

  从上面的代码可以看出,java会自动在导出类的构造器中插入对基类构造器的调用。构造过程是从基类”向外“扩散的,所以基类在导出类构造器可以访问它之前,就已经完成了初始化,这是为了保证父类的完整性。

  子类对象向上转型后会丢失自己的方法,但是会调用父类的方法时,会调用已经被子类覆写的方法。子类独有的方法对父类来说是不可见的,即使通过向上转型。

 

初始化的实际过程:

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

  2、调用基类的构造器

  3、按照声明的顺序调用成员的方法

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

 1 class Cycle{
 2     public Cycle(){
 3         System.out.println("base constructor.");
 4         this.ride();
 5     }
 6     public void ride(){
 7         System.out.println("this is a cycle.");
 8     }
 9 }
10 class Unicycle extends Cycle{
11     private int i=9;
12     @Override
13     public void ride(){
14         System.out.println("this is a Unicycle."+i);
15     }
16 }
17 public class demo02 {
18     public static void main(String[] args) {
19         Unicycle un=new Unicycle();
20         un.ride();
21     }
22 }
23 //output:
24 base constructor.
25 this is a Unicycle.0
26 this is a Unicycle.9

  第29行和第30行不同的原因就是因为初始化步骤1。

  这说明了编写构造器时的一条简单有效的准则:用尽可能简单的方法是对象进入正常状态;如果可以的话,避免调用其他方法。

常见的错误:

  如果你已经定义了一个构造器(无论是否有参数),编译器就不会帮你自动创建默认构造器,那么在子类的构造器中自然就应该使用自定义的构造器,而不是默认构造器。

1 class Toy{
2     Toy(int i){}
3 }
4 class FancyToy extends Toy implements HasBatteries,Waterproof,Shoots{
5     FancyToy(){
6         super(4);    //不可省略
7         //super();       illegal.
8     }
9 }

 

 

转载于:https://www.cnblogs.com/wd-eco/p/java.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值