继承引出的对构造方法的要求

继承引出的对构造方法的要求

构造方法是类的一个特殊成员,它会在实例化对象时被自动调用。我们无法使用对象来调用构造函数,因为在构造函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不能通过对象来调用。

那么我们都知道继承,继承由于派生类继承基类内成员(无法继承构造方法,继承了私有成员,只是无法直接访问),我派生类可以调用基类的成员,那么我派生类肯定要知道基类是如何对自己数据进行初始化的。那么这提出了第一个要求。

  • 派生类一定会调用基类的构造方法。

以C++代码为例,假设我们现在有两个类,基类Person,派生类Student

class Person {
public:
    // constructor with argument
	Person(int x) {
		cout << "Person Constructor with " << x << endl;
	}
};

class Student:public Person {
public:	
    // default constructor without argument
	Student() {
		cout << "Student Default Constructor" << endl;
	}

};

int main (){
    Student a;
}

我们看上面的代码,基类没有无参构造方法,派生类有。我们知道主函数中 Student a 这行代码会隐性调用Student类中默认的无参构造方法。同时,刚刚学到的,也肯定会调用基类Person中的构造方法。但是,这里的代码没有指定会调用基类哪一个构造方法,所以就会调用基类Person默认的无参构造方法。

可是,基类Person没有无参构造方法啊!!!所以这个程序编译器的确会报错,这也就提出了下一个要求。

  • 一定要设计至少2个构造方法,包含1个有参数的构造方法用于初始化成员变量和1个无参数的构造方法设定默认情况。

于是,我们修改代码,

class Person {
public:
    // default constructor
	Person() {
		cout << "Person Default Constructor" << endl;
	}
	// constructor with argument
	Person(int x) {
		cout << "Person Constructor with " << x << endl;
	}
};

class Student:public Person {
public:	
    // default constructor
	Student() {
		cout << "Student Default Constructor" << endl;
	}
	// constructor with argument
	Student(int y)  {
		cout << "Student Constructor with " << y << endl;
	}

};

int main(){
	Student a;
	
	return 0;
}

/*
Output
Person Default Constructor
Student Default Constructor
*/

这样,程序就正常运行了。由于我们是调用了派生类的默认无参构造方法,同样也调用了基类的无参构造方法。

我们可以看到,是先调用了基类的构造方法再调用了派生类的构造方法,符合人们的认知。或者你可以这么想,我是我父母的孩子,我身上的DNA来自于他们,我不得先知道他们的DNA是啥才行吗?所以创建派生类对象时会先调用基类的构造方法。

那么问题来了,我的派生类的构造方法,想显式地调用基类别的构造方法,可以吗?

当然是可以的。

class Person {
public:
	Person() {
		cout << "Person Default Constructor" << endl;
	}

	Person(int x) {
		cout << "Person Constructor with " << x << endl;
	}
};

class Student:public Person {
public:	
    // 调用父类中带参的构造方法
	Student() : Person(10) {
		cout << "Student Default Constructor" << endl;
	}

    // 同样调用父类中带参的构造方法
	Student(int y) : Person(y) {
		cout << "Student Constructor with " << y << endl;
	}

};


int main(){
	Student a(20);
	
	return 0;
}

/*
Output
Person Constructor with 20
Student Constructor with 20

*/
  • 派生类可以指定调用指定的基类构造方法。如果基类的构造方法是无参的,那么在派生类中写不写都可以,不写的话会隐式地调用。
posted @ 2020-03-22 14:08  scyq  阅读(185)  评论(0编辑  收藏  举报