构造器和多态
一.基本介绍
1.1构造器默认为static方法——static方法默认为final方法;
1.2基类构造器调用顺序
检查对象是否被争取构造是构造器的一项任务。
1.1导出类会按照继承层次逐渐向上调用基类构造器,1.2然后按照声明顺序调用成员初始化方法,1.3最后调用导出类构造器主体;
如果没有明确调用(super关键字)哪个基类构造器,则默认调用(无参),若基类没有默认构造器的话编译报错。示例如下:
//编译失败
class Grandfather{
int tag=0;
public Grandfather(int tag) {
this.tag = tag;
}
}
class Father extends Grandfather{
public Father() {
super(1);//去掉这一句,则默认调用基类无参构造函数,编译失败
System.out.println("father");
}
}
//1.1导出类会按照继承层次逐渐向上调用基类构造器,1.2然后按照声明顺序调用成员初始化方法,1.3最后调用导出类构造器主题;
class Grandfather{
int tag=0;
public Grandfather(int tag) {
System.out.println("ground father");
this.tag = tag;
}
}
class Father extends Grandfather{
public Father() {
super(1);
System.out.println("father");
}
}
class Son extends Father{
public Son() {
System.out.println("son");
}
}
public class Demo01 {
public static void main(String[] args) {
new Son();
}
}
output:
ground father
father
son
1.3构造器内部的多态方法的行为
多态方法即导出类重写父类的方法:
- 如果这个方法在父类构造器中使用,则调用的是子类重写后的方法;
- 假若这个方法调用了子类某个变量,则这个变量因为还未在导出类中用其初始化方法,此时分配给变量的存储空间初始化成二进制的0;
示例如下:
class father{
public father() {
func();
}
void func(){ }
}
class son extends father{
int tag=1;
public son(int tag) {
// System.out.println("tag = "+tag);这里默认调用了父类的构造方法;
this.tag = tag;
System.out.println("tag = "+tag);
}
@Override
void func() {
System.out.println("tag = "+tag);
}
}
public class Demo02 {
public static void main(String[] args) {
new son(1);
}
}
output:
tag = 0//分配给对象的存储空间初始化为二进制的零;
tag = 1
由上述可知初始化的实际顺序为:
- 将分配给对象的存储空间初始化为二进制的零;
- 调用基类构造器,构造函数中调用方法为覆盖后的方法;
- 导出类中按照声明顺序调用成员的初始化方法;
- 调用导出类构造器主体;
[注]
- 导出类应该避免调用其他方法,或者调用基类中final方法——不能被改变的方法;
- 导出类能够调用基类构造函数,但没有继承;