继承中,父类和子类构造方法初始化所遇问题
2017-04-23 00:00
549 查看
继承的初始化顺序
1.初始化父类再初始化子类
2.先执行初始化对象中属性,再执行构造方法中的初始化
父类:
子类:
实现类:
运行结果如下:
所以当我们创建一个子类对象时,程序执行顺序是:
是先将 父类的属性初始化 → 父类的构造方法 → 子类的属性初始化 → 子类的构造方法
注意:父类的构造方法是不被子类继承的,它们只能从子类的构造方法中用super()调用。
所以, 当一个类继承了某个类时,在子类的构造方法里,super()必须先被调用;如果你没有写,编译器会自动隐式的调用super()方法,即调用了父类的构造方法,因此执行结果如上。
当编译器自动插入父类构造方法的调用后,子类的构造方法类似如下代码:
==============================================================
如果 子类存在私有属性需要在其构造方法内初始化时
父类:
子类:
报错提示是:Implicit super constructor Animal() is undifined.Must explicitly invoke another constructor
这是一个常见的错误信息:
之所以出现这个编译错误,是因为父类的默认构造方法未定义。
在Java中,如果一个类没有定义构造方法,编译器会默认插入一个无参数的构造方法;
但是如果一个有参的构造方法在父类中已定义,在这种情况,编译器是不会自动插入一个默认的无参构造方法!
对于子类来说,不管是无参构造方法还是有参构造方法,都会默认调用父类的无参构造方法;
当编译器尝试在子类中往这两个构造方法插入super()方法时,因为父类没有一个默认的无参构造方法,所以编译器报错;
2. 移除父类中有参的构造方法
3. 在子类中自己写上父类构造方法的调用;
如:
个人建议最好能为每个类提供一个无参构造方法,以便于对该类进行扩展同时避免错误。
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; }
个人建议最好能为每个类提供一个无参构造方法,以便于对该类进行扩展同时避免错误。
相关文章推荐
- Java子类继承父类,构造方法的执行顺序问题
- java中子类继承父类自动调用父类无参构造方法的问题
- 子类继承父类时,创建对象,构造方法的调用问题
- 关于子类调用父类构造方法的问题
- 子类调用父类构造方法问题
- 关于子类继承父类后调用方法的问题
- 子类和父类构造方法的执行先后问题
- 错误记录--Java中子类继承父类必须调用父类的构造方法?
- Java中子类继承父类方法应该注意的问题
- java中关于子类实例化时调用父类无参构造方法的问题
- java中的继承(子类调用父类构造方法还不懂)
- 解决重写父类的方法且不会影响继承的子类的问题
- 2018/01/08JAVA 基础 / 接口与继承:[Q]:若父类Hero提供了一个有参的构造方法,但是没有提供无参的构造方法。子类应该怎么处理?
- Java继承中父类子类构造方法、静态代码块、非静态代码块的执行顺序
- 关于继承与构造函数重载的问题(初始化子类构造函数中的父类对象)求解答。。。
- Java里子类调用父类构造方法问题
- java继承时,实例化子类,是否会默认调用父类构造方法
- 黑马程序员--java中父类和子类都有构造方法时,子类对象的初始化过程
- 子类继承父类(父类和子类里:块、静态块、构造和方法覆写)之间调用顺序
- Java里子类调用父类构造方法问题