实验4 继承

实验任务2

#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(): programs of draw a circle\n"; }
};


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

运行结果:

 

 

 添加virtual

#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(): programs of draw a circle\n"; }
};


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

运行结果:

 

 

 归纳总结:

同名覆盖原则:派生类与基类中有相同成员时,若未强行指名,则通过派生类对象使用的是派生类的同名成员;

如果要通过派生类的对象访问基类被覆盖的同名成员,需要加 对象名.基类名::同名成员 来限定。

二元作用域分辨符:类名::成员名。

类型兼容原则:派生类对象可以隐含转换为基类对象,即用派生类对象中从基类继承来的成员,逐个赋值给基类对象的成员。

       派生类的对象也可以初始化基类对象的引用。

       派生类对象的地址也可以隐含转换为指向基类的指针。

实验任务3

battery.hpp

#ifndef BATTERY_HPP
#define BATTERY_HPP

#include<iostream>

class Battery{
    private:
        int capacity;
    public:
        Battery(int capacity0):capacity{capacity0}{}
        int get_capacity(){
            return capacity;
        } 
};

#endif

car.hpp

#ifndef CAR_HPP
#define CAR_HPP

#include<iostream>
#include<string>
#include<iomanip>

using namespace std;

class Car{
    private:
        string maker,model;
        int year,odometers;
    public:
        Car(string maker0,string model0,int year0,int odometers0=0):maker{maker0},model{model0},year{year0},odometers{odometers0}{}
        void info(){
            cout<<left<<setw(10)<<"maker:"<<maker<<endl;
            cout<<left<<setw(10)<<"model:"<<model<<endl;
            cout<<left<<setw(10)<<"year:"<<year<<endl;
            cout<<left<<setw(10)<<"odometers:"<<odometers<<endl;
        }
        void update_odometers(int new_odometers);    
};

void Car::update_odometers(int new_odometers){
    if(new_odometers<odometers){
        std::cout<<"Error!";
    }
    else odometers=new_odometers;
} 

#endif 

electricCar.hpp

#define ELECTRICCAR_HPP

#include"car.hpp"
#include"battery.hpp"

#include<iostream>
#include<iomanip>
#include<string>

using namespace std;

class ElectricCar:public Car{
    private:
        Battery battery;
    public:
        ElectricCar(string maker0,string model0,int year0,int capacity0=70,int odometers0=0):Car(maker0,model0,year0,odometers0),battery(capacity0){}
        void info(){
            Car::info();
            cout<<left<<setw(10)<<"capacity:"<<battery.get_capacity()<<"kWh"<<endl;
        } 
};

#endif

task3.cpp

#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<<"--------newcar's info--------"<<endl;
    newcar.info();
}

运行结果:

 

 

实验任务4

pets.hpp

#ifndef PETS_HPP
#define PETS_HPP

#include<iostream>
#include<string>
using namespace std;

class MachinePets{
    private:
        string nickname;
    public:
        MachinePets(const string s):nickname{s}{}
        string get_nickname() const;
        virtual string talk();
};

string MachinePets::get_nickname()const{
    return nickname;
}

string MachinePets::talk(){
    
}

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.cpp

#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-28 23:13  ymmmnn  阅读(32)  评论(2编辑  收藏  举报