您的位置:首页 > 其它

继承中,父类和子类构造方法初始化所遇问题

2017-04-23 00:00 549 查看
继承的初始化顺序
1.初始化父类再初始化子类
2.先执行初始化对象中属性,再执行构造方法中的初始化

父类:

//Animal类为父类
public class Animal {
//在父类中,分别对属性在声明和构造方法中,共进行了2次赋值。看最后运行结果,以此判断谁先初始化
public String name = "第一个名字";

//父类的无参构造方法
public Animal() {
System.out.println("父类:Animal类执行了");
this.name = "第二个名字";
}
}


子类:

//Dog类作为子类,继承自父类Animal
public class Dog extends Animal {

//子类的无参构造方法
public Dog() {
System.out.println("子类:Dog类执行了");
}

}

实现类:

public class Initial {

public static void main(String[] args) {
// 创建一个父类—Animal类对象
Animal animal = new Animal();
System.out.println(animal.name);

System.out.println("====================");

// 创建一个子类—Dog类对象
Dog dog = new Dog();

}

}


运行结果如下:

父类:Animal类执行了
第二个名字
====================
父类:Animal类执行了
子类:Dog类执行了

所以当我们创建一个子类对象时,程序执行顺序是:
是先将 父类的属性初始化 → 父类的构造方法 → 子类的属性初始化 → 子类的构造方法

注意:父类的构造方法是不被子类继承的,它们只能从子类的构造方法中用super()调用。

所以, 当一个类继承了某个类时,在子类的构造方法里,super()必须先被调用;如果你没有写,编译器会自动隐式的调用super()方法,即调用了父类的构造方法,因此执行结果如上。
当编译器自动插入父类构造方法的调用后,子类的构造方法类似如下代码:

public Dog(){
super();
}


==============================================================

如果 子类存在私有属性需要在其构造方法内初始化时
父类:

//Animal类为父类
public class Animal {
public String name;

// 父类的有参构造方法
public Animal(String name) {
this.name = name;
}
}

子类:



报错提示是:Implicit super constructor Animal() is undifined.Must explicitly invoke another constructor



这是一个常见的错误信息:
Implicit super constructor is undefined for default constructor

之所以出现这个编译错误,是因为父类的默认构造方法未定义。
在Java中,如果一个类没有定义构造方法,编译器会默认插入一个无参数的构造方法;
但是如果一个有参的构造方法在父类中已定义,在这种情况,编译器是不会自动插入一个默认的无参构造方法!

对于子类来说,不管是无参构造方法还是有参构造方法,都会默认调用父类的无参构造方法;
当编译器尝试在子类中往这两个构造方法插入super()方法时,因为父类没有一个默认的无参构造方法,所以编译器报错;

有3种解决方法

1. 在父类手动定义一个无参构造方法
2. 移除父类中有参的构造方法
3. 在子类中自己写上父类构造方法的调用;

如:

// 子类的有参构造方法,需要将其私有属性age 和从父类那继承的name一同初始化
public Dog(String name, int age) {
super(name);
this.age = age;
}


个人建议最好能为每个类提供一个无参构造方法,以便于对该类进行扩展同时避免错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: