Essential c++初学 第五章 basic c++ programming

面向对象的编程思维

1.继承,多态和动态绑定
继承的特性让我们得以定义一整群互相有关联的类,并共享接口。多态则是让我们用一种与类型无关的方式来操作这些类对象。
当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。
C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

在静态绑定(又称早绑定)中,调用多态某个函数就会被编译器设定为基类(父类)中的版本,因为函数在编译中就已经确定好了。如果加上虚函数关键字virtual,就会到运行时才会确定好版本。编译器看的是指针的内容,而不是它的类型。因此,由于 b子类 和 c 子类的对象的地址存储在 *shape 中,所以会调用各自的 area() 函数。

#pragma once
#include <iostream>
#include <string>

class LibMat 
{
public:
	LibMat() { std::cout << "LibMat::LibMat() defualt constructor\n"; }
	
	virtual ~LibMat() { std::cout << "LibMat::~LibMat() destructor\n"; }
	virtual void print() const { std::cout << "LibMat::print()--Im a LibMat object"; }

};

void print(const LibMat &mat)
{
	std::cout << "in global print():about to print mat.print()\n";
	mat.print();
}

class  Book :public LibMat 
{
public:
	Book(const std::string &title, const std::string &author)
		:_title(title), _author(author)
	{
		std::cout << "Book::Book("<< _title << "," << _author << ") constructor\n";
	}
	virtual ~Book() { std::cout << "Book::~Book() destructor\n"; }
	virtual void print()const
	{
		std::cout << "Book::print --Im a Book object\n"
			<< "my title is:" << _title << "\n" << "my author is: " << _author << std::endl;
	}

	const std::string title() const { return _title; }
	const std::string author()const { return _author; }


protected:
	std::string _title;
	std::string _author;
};

class AudioBook :public Book
{
public:
	AudioBook(const std::string &title, const std::string &author,
		const std::string &narrator) :Book(title, author), _narrator(narrator)
	{
		std::cout << "AudioBook::AudioBook (" << _title
			<< "," << _author << "," << _narrator << ") constructor\n";
	}
	
	~AudioBook()
	{
		std::cout << "AudioBook::~AudioBook() destructor!\n";
	}
	
	virtual void print() const 
	{
		std::cout << "AudioBook::print()--I am an Audio Book object!\n"
			<< "My title is :" << _title << "\n" << "my author is " << _author << "\n"
			<< "my narrator is:" << _narrator << std::endl;
	}

	const std::string& narrator() const { return _narrator; }

protected:
	std::string _narrator;
};

有了多态,就可以有多个不同的类,都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。

补充如下例:

#include<iostream>
using namespace std;
class Father                    // 基类 Father
{
public:
    void display() {cout<<"Father::display()\n";}
    // 在函数中调用了,子类覆盖基类的函数display() 
    void fatherShowDisplay() {display();} 
};

class Son:public Father                 // 子类Son 
{
public:
    //重写基类中的display()函数
    void display() {cout<<"Son::display()\n";}
};

int main()
{
    Son son;        // 子类对象 
    son.fatherShowDisplay();    // 通过基类中未被覆盖的函数,想调用子类中覆盖的display函数 
    getchar();
}

该例子的运行结果是: Father::display()
可以通过假设来反证,如果说这里fathershowdisplay成功调用了子类的display,那么删除父类的display是不影响程序的,但事实上删除后无法通过编译。

覆盖只是一种抽象概念!! 最终代码由编译器来解析,父类的方法只能调用父类中的方法或父类中的变量。
继承不是父类->子类的复制,父类子类在继承关系中都独立存在,只是调用优先级的关系,使得“覆盖”出现
继承图:
继承关系图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值