实验四:继承

1.实验任务2

程序源码如下:

 1 #include <iostream>
 2 #include<typeinfo>
 3 
 4 class Graph{
 5     public:
 6         virtual void draw(){
 7             std::cout<<"Graph::draw():just as an interface\n";
 8         }
 9 };
10 
11 class Rectangle : public Graph
12 {
13     public:
14         void draw(){
15             std::cout<<"Rectangle::draw(): programs of draw a rectangle\n";
16         }
17 };
18 
19 class Circle : public Graph
20 {
21     public:
22         void draw(){
23             std::cout<<"Circle::draw(): programs of draw a circle\n";
24         }
25 };
26 
27 void fun(Graph *ptr){
28     std::cout << "Pointer type:"<<typeid(ptr).name()<<"\n";
29     std::cout << "RTTI type:"<<typeid(*ptr).name()<<"\n";
30     ptr -> draw();
31 }
32 int main(){
33     Graph g1;
34     Rectangle r1;
35     Circle c1;
36     g1.draw();
37     r1.draw();
38     c1.draw();
39     
40     std::cout << "\n";
41     
42     r1.Graph::draw();
43     c1.Graph::draw();
44     
45     std::cout << "\n";
46     fun(&g1);
47     fun(&r1);
48     fun(&c1);
49 }
View Code

修改之前截图为:

 

 

加virtual修改后的运行结果如图:

 

 

归纳总结:

1.可以观察到运行时ptr成功指向了派生类,但ptr指针本身还是Graph类的。前面的5,6,9数字和字母P是什么还暂时不知道。

2.当派生类出现与基类同名成员时,会优先运行派生类的函数成员,用二元作用域分辨符标识后可运行基类成员

如r1.Graph::draw();   c1.Graph::draw();

3.类型兼容原则:派生类对象可以被当作基类对象使用,但当作基类对象使用时,只能使用作为基类的那一部分接口。因此函数声明成员类型是Graph,draw()必然显示是基类。

2.实验任务3

以下为Battery.hpp

 1 #pragma once
 2 class Battery {
 3 public:
 4     int get_capacity() {
 5         return capacity;
 6     }
 7     Battery(int obj = 70):capacity(obj){}
 8 private:
 9     int capacity;
10 };
Battery.hpp

以下为Car.hpp

 1 #pragma once
 2 #include<iostream>
 3 #include<string>
 4 using namespace std;
 5 class Car {
 6 private:
 7     string maker;
 8     string model;
 9     int year;
10     int odometers;
11 public:
12     Car();
13     Car(string m1, string m2, int y) :maker(m1), model(m2), year(y), odometers(0) {};
14     void info();
15     void update_odometers(int n);
16 };
17 void Car::info() {
18     cout << maker << endl;
19     cout << model << endl;
20     cout << year << endl;
21     cout << odometers << endl;
22 }
23 void Car::update_odometers(int n) {
24     if (n >= odometers)
25         odometers = n;
26     else
27         cout << "data is error!";
28 }
Car.hpp

以下为ElectricCar.hpp

ElectricCar.hpp

以下为task3.cpp

 1 #include <iostream>
 2 #include "electricCar.hpp"
 3 
 4 int main()
 5 {
 6     using namespace std;
 7 
 8     // test class of Car
 9     Car oldcar("Audi", "a6", 2016);
10     cout << "--------oldcar's info--------" << endl;
11     oldcar.update_odometers(25000);
12     oldcar.info();
13 
14     cout << endl;
15 
16     // test class of ElectricCar
17     ElectricCar newcar("Tesla", "model s", 2016);
18     newcar.update_odometers(12500);
19     cout << "\n--------newcar's info--------\n";
20     newcar.info();
21 }
View Code

 

 

 

 3.实验任务四

pets.hpp

 1 #pragma once
 2 #include<string>
 3 #include<iostream>
 4 using namespace std;
 5 class MachinePets {
 6 private:
 7     string nickname;
 8 public:
 9     MachinePets();
10     MachinePets(const string s):nickname(s){}
11     const string get_nickname() {
12         return nickname;
13     }
14     virtual string talk() {
15         return"talk~";
16     }
17 };
18 class PetCats : public MachinePets{
19 public:
20     PetCats(const string st):MachinePets(st){}
21     string talk() {
22         return "miao wu~";
23     }
24 };
25 class PetDogs :public MachinePets{
26 public:
27     PetDogs();
28     PetDogs(const string s1):MachinePets(s1){
29         
30     }
31     string talk() {
32         return "wang!wang!";
33     }
34 };
View Code

 

task4.cpp

 1 #include <iostream>
 2 #include "pets.hpp"
 3 
 4 void play(MachinePets* ptr)
 5 {
 6     std::cout << ptr->get_nickname() << " says " << ptr->talk() << std::endl;
 7 }
 8 
 9 int main()
10 {
11     PetCats cat("miku");
12     PetDogs dog("da huang");
13 
14     play(&cat);
15     play(&dog);
16 }
View Code

测试截图如下:

 

 归纳总结:

1.可以观察到运行时ptr成功指向了派生类,但ptr指针本身还是Graph类的。前面的5,6,9数字和字母P是什么还暂时不知道。

2.当派生类出现与基类同名成员时,会优先运行派生类的函数成员,用二元作用域分辨符标识后可运行基类成员

如r1.Graph::draw();   c1.Graph::draw();

3.类型兼容原则:派生类对象可以被当作基类对象使用,但当作基类对象使用时,只能使用作为基类的那一部分接口。因此函数声明成员类型是Graph,draw()必然显示是基类

4.用typeid().name()获取类型名

5.在继承类中初始化时,构造函数放在大括号前面,不然会出现重定义的问题。

posted @ 2021-11-28 10:56  Beeatbonnie  阅读(30)  评论(3)    收藏  举报