美文网首页
第五章 继承与多态

第五章 继承与多态

作者: DeepWeaver | 来源:发表于2017-11-08 10:03 被阅读27次

学习目的

  1. 掌握派生类的定义和使用;
  2. 掌握派生类构造与析构函数的定义;
  3. 掌握重写基类的成员函数;
  4. 掌握通过基类指针或引用实现多态的方法。

5.2 实习任务

5.2.1 实习任务一

现要定义处理 3 维点的类,而又不能直接修改 Point 类,以 Point 类作为基
类派生得到 Point3D,Point3D 的定义和部分功能已经实现,请补充未完成的部
分成员函数。要求构造函数通过初始化列表实现。
在 Point3D 的 getDistance 方法中,通过调用基类的 getDistance 可 以计算出 XY 平面内的距离 dis,再通过 sqrt(disdis+dzdz)即可计算出 3D 空间 内点的距离。

#include <iostream>
#include <cmath>
using namespace std;
class Point{
public:
    Point():x(0), y(0){}//初始化列表
    Point(double newX, double newY){
        setValue(newX, newY);
    }
    Point(const Point &p){
        setValue(p.getX(), p.getY());
    }
    
    //~Point();
    void setValue(double newX, double newY){
        x = newX;
        y = newY;
    }
    double getX()const{return x;}
    double getY()const{return y;}
    double getDistance(const Point &p2)const{
        return sqrt(pow(x-p2.getX(),2)+pow(y-p2.getY(),2));
    }
    friend double getDistance(const Point &p1, const Point &p2){
                return sqrt(pow(p1.getX()-p2.getX(),2)+pow(p1.getY()-p2.getY(),2));
    }
private:
    double x,y;
};
class Point3D : public Point{
public:
    Point3D(double newX=0, double newY=0, double newZ=0):Point(newX, newY){z = newZ;}
    double getZ() const{return z;}
    double getDistance( const Point3D& p)const{
        return sqrt(pow(this->Point::getDistance(p),2)+pow(z-p.z,2));
    }
private: 
    double z;
};


int main()
{
    // Point p1(3,4);
    // Point p2(5,2);
    // double distance = p1.getDistance(p2);
    // cout<<"Distance:"<<distance<<endl;
    // distance = getDistance(p1,p2);
    // cout<<"Distance:"<<distance<<endl;
    Point p1(3, 4), p2(5,3);
    Point3D p1_3D(3,4,6);
    Point3D p2_3D(2,6,9);
    double dis=p1.getDistance(p2); //计算二维点 p1 和 p2 的距离 
    cout<<"Distance between p1 and p2: "<<dis<<endl; 
    dis=p1_3D.getDistance(p2_3D); //计算 3 维点 p1_3D 和 p2_3D 的距离 
    cout<<"Distance between p1_3D and p2_3D: "<<dis<<endl;
    return 0;
}
运行结果:
Distance between p1 and p2: 2.23607
Distance between p1_3D and p2_3D: 3.74166
[Finished in 0.3s]
修改程序
dis=p2.getDistance(p2_3D); //计算点 p1_3D 和 p2 的距离 
    cout<<"Distance between p1_3D and p2: "<<dis<<endl;
Distance between p1_3D and p2: 4.24264
运行成功!
修改程序
dis=p1_3D.getDistance(p2); //计算点 p1_3D 和 p2 的距离 
cout<<"Distance between p1_3D and p2: "<<dis<<endl;
报错
no viable conversion from 'Point' to 'const Point3D'

【 提示】如果某个函数调用需要传递基类对象,可以将派生类对象传递给他, 此时将发生切片效果,只将基类需要的数据复制过去。相反,如果需要 1 个派生类对象,传递基类对象将无法通过编译。

增加构造函数
Point3D(const Point&p):Point(p),z(0){}
运行成功
Distance between p1_3D and p2: 6.40312

【提示】只含有 1 个参数的构造函数称为类型转换构造函数,可以将传入参数类型转换为当前类类型。如果需要将基类对象复制给派生类对象,可以通过类型转换构造函数间接实现。

5.2.2 实习任务二
#include <iostream>
#include <cmath>
using namespace std;
const double PI = 3.14;
class Shape{
public:
    // double virtual getArea()const{
    //  return 0;
    // }
    double virtual getArea()const=0;
    // double virtual getPerimeter()const{
    //  return 0;
    // }
    double virtual getPerimeter()const=0;
};
class Circle: public Shape{
public:
    Circle(double r): radius(r){}
    double getArea() const;
    double getPerimeter() const;
private:
    double radius;
};
double Circle::getArea()const{
    return PI*radius*radius;
} 
double Circle::getPerimeter()const{
    return 2*PI*radius;
}
class Rectangle: public Shape{
public:
    Rectangle(double w, double h): width(w), height(h){}
    double getArea() const;
    double getPerimeter() const;
private:
    double width;
    double height;
};
double Rectangle::getArea()const{
    return width*height;
}
double Rectangle::getPerimeter()const{
    return 2*(width + height);
}
class Triangle: public Shape{
public:
    Triangle(double newA, double newB, double newC):a(newA),b(newB),c(newC){}
    double getArea()const;
    double getPerimeter()const;
private:
    double a,b,c;
};
double Triangle::getArea()const{
    double p = this->getPerimeter() / 2.0;//p是半周长,这个别搞错了
    return sqrt(p*(p-a)*(p-b)*(p-c));

}
double Triangle::getPerimeter()const{
    return a+b+c;
}
void outputInfo(const Shape&sh);
void outputInfo(const Shape& sh){
    cout<<"Area:"<<sh.getArea()<<endl;
    cout<<"Perimeter:"<<sh.getPerimeter()<<endl;
}
int main(){
    //Shape shape0;
    Rectangle shape1(3,4);
    Circle shape2(1.0);
    Triangle shape3(3,4,5);
    shape3.getArea();
    // outputInfo(shape0);
    outputInfo(shape1);
    outputInfo(shape2);
    outputInfo(shape3);

    return 0;
}
运行结果:
Area:12
Perimeter:14
Area:3.14
Perimeter:6.28
Area:6
Perimeter:12
[Finished in 0.3s]

课后练习

#include <iostream>
using namespace std;
class Base{
public:
    void display(){cout<<"Base display"<<endl;}
};
class Derived: public Base{
public:
    void display(){cout<<"Derived display"<<endl;}
};
void display(Base & rr){
    rr.display();
}
int main(){
    Base b;
    Derived d;
    display(b);
    display(d);
    return 0;
}
运行结果:
Base display
Base display
[Finished in 0.3s]

另:

void display(Derived & rr){
    rr.display();
}
int main(){
    Base b;
    Derived d;
    b = d;// d = b报错
    // display(b);
    display(d);
    return 0;
}
Derived display
[Finished in 0.3s]
#include <iostream>
using namespace std;
class Person{
public:
    Person(){
        cout<<"Person constructed!"<<endl;
    }
    ~Person(){
        cout<<"Person destructed!"<<endl;
    }
};
class Student: public Person{
public:
    Student(){cout<<"Student constructed!"<<endl;}
    ~Student(){cout<<"Student destructed"<<endl;}
};
class Teacher: public Person{
public:
    Teacher(){
        cout<<"Teacher constructed!"<<endl;
    }
    ~Teacher(){
        cout<<"Teacher destructed!"<<endl;
    }
    
};
int main(){
    Student s;
    Teacher t;
    return 0;
}

因缺思婷 results ↓

运行结果:
Person constructed!
Student constructed!
Person constructed!
Teacher constructed!
Teacher destructed!
Person destructed!
Student destructed
Person destructed!
[Finished in 0.3s]
#include <iostream>
using namespace std;
class Animal{
public:
    virtual void Report(){cout<<"Report from Animal!"<<endl;}
};
class Tiger: public Animal{
public:
    virtual void Report(){cout<<"Report from Tiger!"<<endl;}
};
class Monkey: public Animal{
public:
    virtual void Report(){
        cout<<"Report from Monkey!"<<endl;
    }
};
void show(Animal *p){
    p->Report();
}
int main(){
    Tiger tiger;
    Monkey monkey;
    Animal animal = tiger;
    show(&tiger);
    show(&monkey);
    show(&animal);
    return 0;
}
运行结果:
Report from Tiger!
Report from Monkey!
Report from Animal!
[Finished in 0.3s]
#include <iostream>
using namespace std;
class Base{
private:
    int base;
public:
    Base(int b){
        base = b;
        cout<<"base = "<<b<<endl;
    }
    ~Base(){}
};
class Derived: public Base{ //按照base->derived的顺序赋值
private:
    Base bb;
    int derived;
public:
    Derived(int d, int b, int c):bb(c),Base(b){
        derived = d;
        cout<<"derived = "<<derived<<endl;
    }
    ~Derived(){}
};
int main(){
    Derived d(3,4,5);
    return 0;
}
运行结果:
base = 4
base = 5
derived = 3
[Finished in 0.3s]
#include <iostream> 
using namespace std; 
class Base{
public:
    Base (int i,int j){ x0=i; y0=j;}
    void Move(int x,int y){ x0+=x; y0+=y;}
    void Show(){ cout<<"Base("<<x0<<","<<y0<<")"<<endl;}
private:
    int x0,y0;
};
class Derived: private Base{ 
public:
    Derived(int i,int j,int m,int n):Base(i,j){ x=m; y=n;}
    void Show (){cout<<"Next("<<x<<","<<y<<")"<<endl;} 
    void Move1(){Move(2,3);}
    void Show1(){Base::Show();}
private: 
    int x,y;
};
int main( ){
    Base b(1,2); 
    b.Show();
    Derived d(3,4,10,15); 
    d.Move1(); 
    d.Show();
    d.Show1();
    return 0;
}
Base(1,2)
Next(10,15)
Base(5,7)
[Finished in 0.3s]
#include <iostream> 
#include <string> 
#include <vector> 
using namespace std; 
class Sales{
private:
    string product;
    double price;
    double quantity; 
public:
    Sales(string prod,double p,double q):product(prod),price(p),quantity(q){}
    virtual double net_price()const{return price*quantity;} 
};
class DiscountSales:public Sales{ 
private:
    double rate; 
public:
    DiscountSales(string prod,double p,double q,double r) :Sales(prod,p,q),rate(r){}
virtual double net_price()const{return Sales::net_price()*rate;} 
};
class FullDiscountSales:public Sales{ 
private:
    double fullMoney,discountMoney; 
public:
    FullDiscountSales(string prod,double p,double q,double f,double d) :Sales(prod,p,q),fullMoney(f),discountMoney(d){}
    virtual double net_price()const{
        double money=Sales::net_price();
        int count=0;
        while((money-=fullMoney)>=0) {count++;} 
        return Sales::net_price()-count*discountMoney;
    } 
};
int main(){
    vector< Sales* > vec;
    vec.push_back(new DiscountSales("C++",100,2,0.8)); 
    vec.push_back(new FullDiscountSales("Java",80,5,200,30)); 
    cout<<vec[0]->net_price()<<endl; 
    cout<<vec[1]->net_price()<<endl;
    double totalPrice=0;
    for(auto p : vec) totalPrice+=p->net_price(); 
        cout<<"totalPrice:"<<totalPrice<<endl;
    for(auto p: vec) delete p;
return 0;
}
运行结果:
160
340
totalPrice:500
[Finished in 0.4s]

相关文章

  • 面向对象

    继承与多态

  • 程序组第二次作业代码

    继承与多态: 接口作业:

  • 第五章 继承与多态

    学习目的 掌握派生类的定义和使用; 掌握派生类构造与析构函数的定义; 掌握重写基类的成员函数; 掌握通过基类指针或...

  • 《Java8学习笔记》读书笔记(七)

    第6章 继承与多态 学习目标 了解继承的目的 了解继承与多态的关系 知道如何重写方法 认识java.lang.Ob...

  • golang-面向对象

    思考:go语言不支持继承与多态的优点与缺点是什么 go语言只支持封装,不支持继承与多态 go语言没有class,只...

  • js-继承和闭包

    继承和闭包 一、面向对象的三大特征 封装 继承 多态 二、什么是继承 继承是面向对象软件技术当中的一个概念,与多态...

  • PHP学习2

    六.继承与多态 1. 类的组合和继承(继承===“是、像”、“父与子”,组合===“需要”、“整体与局部”) 组合...

  • 2020-05-16--Java--day09【继承、super

    1.继承 三大特征:封装,继承,多态 继承是多态的前提,没有继承就没有多态 继承的主要解决的问题就是:共性抽取 在...

  • Java多态及相关

    面向对象有三大特征:封装、继承、多态。从一定角度看,封装与继承是为多态准备的。多态也是面向对象中最重要的概念。 多...

  • Lession08继承和多态

    继承 多态 继承练习

网友评论

      本文标题:第五章 继承与多态

      本文链接:https://www.haomeiwen.com/subject/xokemxtx.html