实验4 继承
实验任务2
<task2.cpp>
1 #include<iostream> 2 #include<typeinfo> 3 4 class Graph 5 { 6 public: 7 void draw(){std::cout << "Graph::draw() : just as an interface\n";} 8 }; 9 10 class Rectangle : public Graph 11 { 12 public: 13 void draw(){std::cout <<"Rectangle::draw() : programs of draw a rectangle\n";} 14 }; 15 16 class Circle : public Graph 17 { 18 public: 19 void draw(){std::cout <<"Circle::draw() : programs of draw a circle\n";} 20 }; 21 22 void fun(Graph *ptr) 23 { 24 std::cout << "pointer type: " << typeid(ptr).name() << "\n"; 25 std::cout << "RTTI type: " << typeid(*ptr).name() << "\n"; 26 ptr->draw(); 27 } 28 int main() 29 { 30 Graph g1; 31 Rectangle r1; 32 Circle c1; 33 34 g1.draw(); 35 r1.draw(); 36 c1.draw(); 37 38 std::cout << "\n"; 39 40 r1.Graph::draw(); 41 c1.Graph::draw(); 42 43 std::cout << "\n"; 44 45 fun(&g1); 46 fun(&r1); 47 fun(&c1); 48 }
运行结果:
同名覆盖原则:派生类和基类具有相同成员时,通过派生类对象访问,默认访问的是派生类的同名成员
二元作用域分辨符(::):用于显式指定使用的是哪个类的重名成员
类型兼容原则:派生类对象也可以当作基类对象来使用,但只能使用从基类继承的那部分功能
在Graph类的成员函数draw()前加上virtual,重新编译运行。结果为:
调用虚函数时,根据指针实际指向的对象,选择相应的函数实现。
实验任务3
使用类的组合和继承模拟简单的车辆信息管理。
<battery.hpp>
1 #ifndef BATTERY_HPP 2 #define BATTERY_HPP 3 4 class Battery 5 { 6 public: 7 Battery(int cap=70):capacity{cap}{} 8 //Battery(Battery& b):capacity(b.capacity){} 9 int get_capacity(){return capacity;} 10 private: 11 int capacity; 12 }; 13 #endif
<car.hpp>
1 #ifndef CAR_HPP 2 #define CAR_HPP 3 4 #include <iostream> 5 #include <iomanip> 6 using namespace std; 7 class Car 8 { 9 public: 10 Car() = default; 11 Car(string ma, string mo, int y, int meters = 0); 12 void info(); 13 void update_odometers(int meters); 14 15 string maker; //制造商 16 string model; //型号 17 int year; //生产年份 18 int odometers; //行车里程数 19 }; 20 21 Car::Car(string ma, string mo, int y, int meters) 22 { 23 maker = ma; 24 model = mo; 25 year = y; 26 odometers = meters; 27 } 28 29 void Car::info() 30 { 31 cout.setf(ios::left); 32 cout << setw(20) << "maker:" << maker << endl; 33 cout << setw(20) << "model:" << model << endl; 34 cout << setw(20) << "year:" << year << endl; 35 cout << setw(20) << "odometers:" << odometers << endl; 36 } 37 38 void Car::update_odometers(int meters) 39 { 40 if (meters < odometers) 41 cout << "new odometers is wrong!!!" << endl; 42 else 43 { 44 odometers = meters; 45 } 46 } 47 #endif
<electricCar.hpp>
1 #ifndef ELECTRICCAR_HPP 2 #define ELECTRICCAR_HPP 3 4 #include"battery.hpp" 5 #include"car.hpp" 6 using namespace std; 7 8 class ElectricCar : public Car 9 { 10 public: 11 ElectricCar(string ma,string mo,int y,int cap=70,int meters=0):Car(ma,mo,y,meters),battery(cap){} 12 void info(); 13 private: 14 Battery battery; 15 }; 16 17 void ElectricCar::info() 18 { 19 cout.setf(ios::left); 20 cout << setw(20) << "maker:" << maker << endl; 21 cout << setw(20) << "model:" << model << endl; 22 cout << setw(20) << "year:" << year << endl; 23 cout << setw(20) << "odometers:" << odometers << endl; 24 cout << setw(20) << "capacity:" << battery.get_capacity() <<"-kWh"<< endl; 25 } 26 #endif
<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("BWM", "a4", 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 A", 2016); 18 newcar.update_odometers(5000); 19 cout << "\n--------newcar's info--------\n"; 20 newcar.info(); 21 }
测试结果:
实验任务4
使用类的继承,模拟简单的机器宠物。
<pets.hpp>
1 #ifndef PETS_HPP 2 #define PETS_HPP 3 4 using namespace std; 5 class MachinePets 6 { 7 public: 8 MachinePets(const string s) : nickname{s} {} 9 string get_nickname() const { return nickname; } 10 virtual string talk() { return "ze~ze~"; } 11 12 private: 13 string nickname; 14 }; 15 16 class PetCats : public MachinePets 17 { 18 public: 19 PetCats(const string s) : MachinePets(s) {} 20 string talk() 21 { 22 return "miao wu~"; 23 } 24 }; 25 26 class PetDogs : public MachinePets 27 { 28 public: 29 PetDogs(const string s) : MachinePets(s) {} 30 string talk() 31 { 32 return "wang wang~"; 33 } 34 }; 35 #endif
<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 }
测试结果:
总结与体会
1、加了{}就是定义了,而不是声明
2、派生类构造函数初始化,通过参数化列表,先调用基类构造函数初始化基类,再初始化派生类成员
3、有默认值的形参才可以没有实参