完成类、继承和多态一章

This commit is contained in:
lion187 2018-07-23 21:36:11 +08:00
parent 86ee65c4dc
commit f3504c9734
3 changed files with 147 additions and 34 deletions

5
.gitignore vendored
View File

@ -3,3 +3,8 @@
*.tmproject
tmtags
Makefile
*.cpp
*.hpp
*.exe
*.json

View File

@ -1,75 +1,184 @@
# 2.10 类、继承和多态
## 2.10.1 类
## 2.10.1 类和多态
在 C++ 中,我们通过如下方法定义和实现一个类:
在 C++ 中,我们通过如下方法定义和实现一个类:
```cpp
/**
* @file   Tree.h
* @file   Animal.hpp
*/
class Tree
#pragma once // 只被编译一次.
#include <string> // 使用 C++ 的 string 类.
using namespace std; // 使用 std 命名空间.
class Animal
{
public:
  Tree();
~Tree();
Animal(); // 构造函数.
virtual ~Animal(); // 析构函数.
virtual void Sound(void);
  char Color[3];
  double Height;
  double Width;
char Color[3]; // 属性.
double Height;
double Width;
protect:
  virtual void Growth(void);
  virtual void Growth(double rate);
protected:
virtual void Growth(void); // 方法.
virtual void Growth(double rate);
  string Shape;
string Sounds;
private:
  void Haha(void);
void MakeSounds(void);
  long Nothing;
string Shape;
};
}
```
对应的实现为:
可以看到Animal 类中有两个参数不同的 Growth 方法,这被称作多态,在使用 Animal 对象时,依据调用 Growth 方法时传入的参数个数和类型来判断具体使用哪个 Growth 方法。Animal 类的实现为:
```cpp
/**
* @file   Tree.cpp
* @file   Animal.cpp
*/
#include <Tree.h>
#include "Animal.hpp"
#include <iostream>
using namespace std;
Tree::Tree()
Animal::Animal()
{
  this->Height = 8.5;
this->Height = 8.5;
this->Sounds = "Bebe...";
}
Tree::~Tree()
Animal::~Animal()
{
cout<<"Dead."<<endl;
}
void Tree::Growth(void)
void Animal::Sound(void)
{
  Height += 0.2;
  Width += 0.1;
this->MakeSounds();
}
void Tree::Growth(double rate)
void Animal::Growth(void)
{
  Height *= (1+rate);
Height += 0.2;
Width += 0.1;
}
void Animal::Growth(double rate)
{
Height *= (1+rate);
Width *= (1+rate);
}
void Tree::Haha(void)
void Animal::MakeSounds(void)
{
  cout<<"Nothing to do."<<endl;
cout<<Sounds<<endl;
}
```
在这个类里,我们实现了公有,保护和私有属性和方法。提供了虚方法以允许子类对虚方法进行覆盖。还提供了 Growth 方法的多态实现。
## 2.10.2 继承
## 2.10.2 继承和多态
动物这个类下有多个子类,比如说可爱的小狗,它继承于 Animal 这个类,如下:
```cpp
/**
* @file   Dog.hpp
*/
#pragma once
#include "Animal.hpp"
class Dog : public Animal
{
public:
Dog();
virtual ~Dog();
protected:
virtual void Growth(void);
virtual void Growth(double rate);
virtual void Growth(double height, double width);
};
```
可以看到Dog 类覆盖了 Animal 类中两个 Growth 方法,并且通过多态扩充了一个 Growth 方法。看下 Dog 类的实现:
```cpp
/**
* @file   Dog.cpp
*/
#include "Dog.hpp"
#include <iostream>
Dog::Dog()
{
this->Height = 0.6;
this->Sounds = "Wang!Wang!Wang!";
}
Dog::~Dog()
{
cout<<"Dog Dead. Wu...Wu...T_T..."<<endl;
}
void Dog::Growth(void)
{
Height += 0.03;
Width += 0.03;
}
void Dog::Growth(double rate)
{
Height *= (1+rate);
Width *= (1+rate);
}
void Dog::Growth(double height, double width)
{
Height = height;
Width = width;
}
```
在 Dog 类的构造函数中,将 Sounds 属性赋值成了 "Wang!Wang!Wang!" 的狗叫声,当我们调用 Dog 对象的 Sound 方法时,就会出现 "Wang!Wang!Wang!" 而不是 Animal 中的 "Bebe..."。这是因为,在初始化 Dog 对象时,先调用了 Animal 的默认构造函数,对来自父类的属性进行了初始化之后,又调用了 Dog 的构造函数,在 Dog 的构造函数中,再次初始化 Sounds 属性,覆盖了原有的 Animal 中的赋值。
下面我们看看在 main 函数中如何调用这两个类:
```cpp
/**
* @file   main.cpp
*/
#include <Animal.hpp>
#include <Dog.hpp>
int main() {
Animal* animal;
animal = new Animal();
animal->Color[1] = 255;
animal->Sound(); // 输出 Bebe...
delete animal; // 输出 Dead.
Dog* dog;
dog = new Dog();
dog->Color[0] = 255;
dog->Growth(0.2); // 调用 Animal 类中的 void Growth(double rate) 方法.
dog->Sound(); // 输出 Wang!Wang!Wang!
delete dog; // 输出 Dog Dead. Wu...Wu...T_T... 和 Dead.
return 0;
}
```
通过 dog 调用 Growth 方法那句,更能体现类抽象的实质。
## 练习
编写“人类”继承于 Animal 类,扩充其“姓名”和“性别”属性,编写“学生”类继承于“人类”,扩充其“成绩”属性,基于这些类,实现学生成绩录入和现实系统。

View File

@ -45,6 +45,5 @@ class 的概念与现实中的类概念一致,它是具有相同特性群体
C++ 是面向对象思想的最佳实现。它扩充了 C 语言并降低了二次学习的成本。C++ 非常完整的继承了面向对象思想,并在语言层面提供了面向对象工具。在 C++ 类内部,可以有多个同名方法,但他们的参数个数或参数类型不同,这一特性,被称作多态。
## 练习
以身边事物为参考,举出父类和多个子类的例子,并说出哪些是属性,哪些是方法,哪里提现出了继承,覆盖和多态思想。