实践四 继承

//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);
}

 

 

posted @ 2021-11-24 22:09  予你一叶舟  阅读(8)  评论(1编辑  收藏  举报