实践四 继承
//task2 #include<iostream> #include<typeinfo> //definitation of Graph class Graph { public: void draw() { std::cout << "Graph::draw():just as an interface\n"; } }; //definition of Rectangle,derived from Graph class Rectangle :public Graph { public: void draw() { std::cout << "Rectangle::draw():programs of draw a rectangle\n"; } }; //definition of Circle,derived from Graph class Circle :public Graph { public: void draw() { std::cout << "Circle::draw():program of draw a Circle\n"; } }; //definition of fun():as a call interface void fun(Graph* ptr) { std::cout << "pointer type:" << typeid(ptr).name() << "\n"; std::cout << "RTTI type:" << typeid(*ptr).name() << "\n"; ptr->draw(); } //test int main() { Graph g1; Rectangle r1; Circle c1; //call by object name g1.draw();
r1.draw(); c1.draw(); std::cout << "\n"; //call by object name,and using the scope resolution operator:: r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; //call by pointer to Base class fun(&g1); fun(&r1); fun(&c1); }
//task2 #include<iostream> #include<typeinfo> //definitation of Graph class Graph { public: virtual void draw() { std::cout << "Graph::draw():just as an interface\n"; } }; //definition of Rectangle,derived from Graph class Rectangle :public Graph { public: void draw() { std::cout << "Rectangle::draw():programs of draw a rectangle\n"; } }; //definition of Circle,derived from Graph class Circle :public Graph { public: void draw() { std::cout << "Circle::draw():program of draw a Circle\n"; } }; //definition of fun():as a call interface void fun(Graph* ptr) { std::cout << "pointer type:" << typeid(ptr).name() << "\n"; std::cout << "RTTI type:" << typeid(*ptr).name() << "\n"; ptr->draw(); } //test int main() { Graph g1; Rectangle r1; Circle c1; //call by object name g1.draw(); r1.draw(); c1.draw(); std::cout << "\n"; //call by object name,and using the scope resolution operator:: r1.Graph::draw(); c1.Graph::draw(); std::cout << "\n"; //call by pointer to Base class fun(&g1); fun(&r1); fun(&c1); }
同名覆盖原则:
派生类与基类有相同成员的时候,如果没有进行别的说明,则通过派生类的对象使用的是派生类里的同名成员,如果派生类想使用基类的成员,则派生类的函数构造时的形势为:派生类名(形参1,形参2):基类名(形参1,形参2)。
二元作用域分辨符:
如果派生类想要访问基类中同名的数据成员或者函数成员,则需要通过这样的形式: 派生类对象名.基类名::数据成员/函数成员
类型兼容原则:子类对象可以当作父类对象使用;子类对象可以直接赋值给父类对象;子类对象可以直接初始化父类对象;父类指针可以直接指向子类对象;父类引用可以直接引用子类对象,替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继承的成员。
Task3
//Battery.hpp #ifndef BATTERY_H #define BATTERY_H #include<iostream> using namespace std; class Battery { private: int capacity; public: Battery(int capacity0 = 70) :capacity{ capacity0 } {}; int get_capacity() { return capacity; } }; #endif
//Car.hpp #ifndef Car_H #define Car_H #include<iostream> #include<string> using namespace std; class Car { private: string maker; string model; int year; int odometers; public: Car() {}; Car(string maker0, string model0, int year0, int odometers0 = 0) :maker{ maker0 }, model{ model0 }, year{ year0 }, odometers{ odometers0 }{}; void info() { cout << "制造商:\t\t" << maker << endl; cout << "型号:\t\t\t" << model << endl; cout << "生产年份:\t\t" << year << endl; cout << "当前行车里程数:\t" << odometers << endl; } void update_odometers(int odometers0) { if (odometers0 < odometers) cout << "更新的行车里程数有误!" << endl; else odometers = odometers0; } }; #endif
//ElectricCar.hpp #ifndef ELECTRICCAR_H #define ELECTRICCAR_H #include<iostream> #include<string> #include"Car.hpp" #include"Battery.hpp" using namespace std; class ElectricCar :public Car { private: Battery battery; public: ElectricCar(string maker0, string model0, int year0, int odometers0 = 0) :Car(maker0, model0, year0, odometers0) {}; void info() { Car::info(); cout << "当前的电池容量:\t" << battery.get_capacity() <<"-KMh"<< endl; } }; #endif
//task3.hpp #include<iostream> #include"ElectricCar.hpp" int main() { using namespace std; //test class of car Car oldcar("Audi", "a4", 2016); cout << "------------oldcar's info------------" << endl; oldcar.update_odometers(25000); oldcar.info(); cout << endl; //test class of ElectricCar ElectricCar newcar("Tesla", "model s", 2016); newcar.update_odometers(2500); cout << "\n---------newcar's info--------\n"; newcar.info(); }
Task4
//pets.hpp #ifndef PETS_H #define PETS_H #include<iostream> #include<string> using namespace std; class MachinePets { private: string nickname; public: MachinePets(const string s) :nickname{ s } {}; virtual string talk() = 0; string get_nickname()const { return nickname; } }; class PetCats :public MachinePets { public: PetCats(const string s) :MachinePets(s) {}; string talk() { return "miao wu~"; } }; class PetDogs :public MachinePets { public: PetDogs(const string s) :MachinePets(s) {}; string talk() { return "wang wang!"; } }; #endif
//task4 #include<iostream> #include"pets.hpp" void play(MachinePets *ptr) { std::cout << ptr->get_nickname() << " says " << ptr->talk() << std::endl; } int main() { PetCats cat("miku"); PetDogs dog("da huang"); play(&cat); play(&dog); }