Java 构造⽅法的继承构造⽅法的调⽤顺序(⼀)
我们知道,在java中,类的实例化由 内存分配 + 构造两步完成的,如果这个类存在⽗类,那么它的构造过程其实是由其 ⽗类.构造() + ⼦类.构造()共同完成的。由于java中,所有的类都是继承⾃Object,所以其实所有的类的实例化过程中都包含类它的⽗类的构造过程,编译器会隐式地为我们加上每个类的super(),除⾮某个⽗类⽆参构造函数不存在。
如下所⽰:成员赋值 这⼀步取决于类在定义时是否已对成员变量指定值。
在这个过程中,其实也是有⼀些规则,那就是⼦类的构造是编译器默认调⽤⽗类.构造(void)⽆参⽅法,如果⽗类中并没有定义⽆参,那么就会出现编译报错。如果⽗类中只有带参数构造⽅法(此情况下,⽗类没有定义⽆参构造⽅法),由于编译器并不会调⽤带参数构造⽅法,那么在⼦类的构造⽅法中,必须由我们显式调⽤⽗类的带参数构造⽅法,否则 ⽗类.构造() + ⼦类.构造()的这个过程会⽆法完成,编译器会报错那么有⼈会问到,类不是有默认的⽆参构造⽅法么?怎么会有你说的这种情况呢?
其实类只有两种情况存在⽆参构造⽅法: 1、在没有显式定义任何⼀个构造⽅法的时候,默认存在⼀个⽆参数构造⽅法, 2、在类中显式定义⼀个⽆参构造⽅法。
有⼀种情况会导致类没有⽆参构造⽅法: 那就是⼀个类中存在⼀个或者多个构造⽅法,并且这些构造⽅法都是有参数的
如果⽗类是⼀个,那么会产⽣怎么样⼀种情况呢?
我们来看⼀段代码,假如⼀个抽象类Money 存在 成员amount,并且该抽象类没有定义⽆参数构造⽅法,另⼀个类USD继承⾃这个类;⽗类Money :
这⾥解释⼀下,抽象类其实也是有构造⽅法的,只不过抽象类是不能被实例化,也就是说,抽象类的构造⽅法不能在对抽象类进⾏实例化的场合调⽤。在java中,抽象类的构造⽅法⽤于⼦类访问⽗类数据的初始化,⼀旦⼀个普通类继承了抽象类,便可以在这个⼦类的构造⽅法中调⽤其⽗抽象类的构造⽅法。
我们将在下⾯的代码中来介绍这样⼀种特殊情况。
⼦类USD:内存分配-----> 构造(⽗类.成员赋值--⽗类.构造() + ⼦类.成员赋值--⼦类.构造())
1public abstract class Money { private double amount = 0; //类在定义时已对成员变量指定值为0,那么构造过程会多⼀步⽗类.成员赋值 public Money (double amount ){ this .amount = amount ; //⽗类只有⼀个带参数⽅法,也就没有默认的⽆参数构造⽅法了 } public void setAmount (double am ){ this .amount = am ; } public double getAmount (){ return this .amount ; } public abstract String getCurrencyName ();}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
在这个例⼦中,我们看到,⼦类USD的构造⽅法中必须显式地调⽤⽗抽象类的构造⽅法,这也说明继承了抽象类的⼦类的构造过程同样也是⽗类.构造() + ⼦类.构造()共同完成的。
最后,我们在这段⽰例代码中,来看⼀下private 成员的继承,
我们可以看到,⼦类USD继承来⽗类Money 的private amount成员,但是并不能直接访问该成员,
⼦类必须通过⽗类的public/protected⽅法来访问这个成员。 class USD extends Money { public USD () { super (4); //⼦类的构造⽅法必须显式调⽤⽗类的构造⽅法,否则编译器报错 //⼦类的构造⽅法调⽤了⽗类的构造⽅法,但是并不是实例化了⼀个⽗类对象,它只是⼦类实例化过程中的⼀部分 } public double getAmount (){ return super .getAmount (); } public String getCurrencyName (){ return "USD"; } public void setCurrencyName (double x ){ super .setAmount (x ); }}
1
2
3
4
5
java接口有没有构造方法6
7
8
9
10
11
12
13
14
15
16
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论