package day11;
/**
* 在创建子类对象时,为了初始化从父类继承来的数据成员,
* 系统需要调用其父类的构造方法。
*
* 构造原则如下:
1. 如果子类没有定义构造方法,则调用父类的无参数的构造方法。
2. 如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类无参数的构造方法,然后执行自己的构造方法。
3. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数,则会调用父类的默认无参构造函数。
4. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构造函数。
5. 在创建子类对象时候,如果子类的构造函数没有显示调用父类的构造函数且父类只定义了自己的有参构造函数,则会出错(如果父类只有有参数的构造方法,则子类必须显示调用此带参构造方法)。
6. 如果子类调用父类带参数的构造方法,需要用初始化父类成员对象的方式
*
* 子类在创建的时候 会自动调用父类对应的构造函数
*
* 但是父类的构造函数又不能被子类继承【为什么】
* 想必是 Java 语言设计者,要求子类有责任保证它所继承的父类尽快进入到一个稳定、完整的状态中。
* 试想,如果没有这个约束,那么子类的某个继承自父类的方法可能会使用到父类中的一些变量,而这些
* 变量并没有进行初始化,从而产生一些难以预料的后果,因此构造子类的对象前,必须构造父类的对象,
* 并将之隐含于子类对象之中,使用关键字super引用父类对象。
*
*
* 【问题】
* 创建子类的时候,希望能通过子类来初始化从父类继承过来的属性,但是又不能直接调用
* 父类的构造函数,用this关键字不合适,因为这是父类的属性,用父类的构造函数更加合适
* 【原因】
* 在父类的构造函数中,可能存在初始化操作的一个限制和约束,这个限制和约束是为了保证
* 项目合法性的业务逻辑符合生活的要求但是如果在子类中直接使用this来赋值继承而来的父类属性,
* 没有通过判断和约束,可能会导致代码的业务逻辑出现问题
*
* super 关键字 调用父类方法的关键字
* super关键字的细节
* 1、super关键字可以调用父类的成员方法和构造函数,它调用构造函数的规则好
* 似this 非常像如果调用构造函数,必须在代码块的第一行
* 2、如果在代码中,没有【显示】调用父类的构造函数,那么java编译器会在代码
* 的编译阶段,自动帮你补出一个符合条件的父类构造函数【隐士】调用
* 3、如果在子类中需要对父类的属性进行初始化操作,那么只能通过super关键字来调用
* 父类的构造函数,不能在子类的构造函数中直接用this赋值
* 4、super和this不能在同一个构造函数中去调用其他的构造函数,因为super和this
* 调用构造函数的时候,必须在代码的第一行,如果同时调用,总有一方不符合条件。
* @author Administrator
*
*/
class Fu{
int age;
int height;
public Fu() {
System.out.println("父类的无参构造函数");
}
public Fu(int age,int height) {
//构造函数要对初始化的参数有一定的判断和限制
if(age <= 0 || height <= 0) {
this.age = 1;
this.height = 1;
}else {
this.age = age;
this.height = height;
}
}
public void speak() {
System.out.println("犯我中华者,虽远必诛");
}
}
class Zi extends Fu{
int id;
public Zi(int id){
this.id = id;
System.out.println("子类自己属性的构造函数");
}
public Zi(int age, int height,int id) {
//age height 来源于父类
super(age,height); //使用关键字调用父类的构造函数
//this(id);
this.id = id;
System.out.println("子类的初始化父类属性的构造函数");
}
public void test() {
super.speak(); //使用super关键字来调用父类的方法
}
}
public class Test02 {
public static void main(String[] args) {
Zi son = new Zi(10);
Zi erzi = new Zi(10,120,9);
erzi.test();
}
}