面向对象程序设计——虚函数和多态性

一、实验目的:

  1. 掌握动态联编的概念;
  2. 掌握虚函数和纯虚函数的使用方法;
  3. 掌握抽象类的使用。

二、实验内容:

在前面实验基础上,完成以下内容:

(1)在基类Account中添加deposit、withdraw、settle这3个函数的声明,且将它们都声明为纯虚函数,通过基类的指针可以调用派生类的相应函数。

(2)将show函数声明为虚函数,通过基类的指针来调用派生类的show函数。

(3)将计算两个日期相差天数的distance函数改为“—”运算符重载函数,使得计算两个日期相差天数更直观,增加程序的可读性。

提示:

储蓄账户一年算一次利息,而信用账户一月算一次利息。而使用基类指针来调用settle函数时,事先并不知道该指针所指向对象的具体类型,无法决定采用何种方式调用settle函数,因此只能将二者允许接收的参数统一为每月1日。同时对储蓄账户的settle函数进行修改,使它在结算利息之前先判断是否为1月,只有参数所给的日期是1月时才进行结算。

Main.cpp:

#include<iostream>
#include "account.h"
using namespace std;
Account::Account(int Id,double Balance)
{
    id=Id;
    balance=Balance;
}
void Account::show()
{
    cout<<"\t账号:"<<getId()<<"\t\t余额:"<<getBalance()<<"元"<<endl;
}
void Account::getTotal()
{
    cout<<"\t所有账户总金额:"<<total<<"元"<<endl;
}
SavingsAccount::SavingsAccount(int year,int month,int day,int id,double balance,double Rate):Account(id,balance),lastDate(year,month,day)
{
    rate=Rate;
    cout<<year<<"年"<<month<<"月"<<day<<"日";
    cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
const double SavingsAccount::accumulate(Date date)
{
    return (lastDate-date)*balance;
}
void SavingsAccount::deposit(Date date,double amount)
{
    accumulation+=accumulate(date);
    balance+=amount;
    lastDate = date;
    total+=amount;
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"存入:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::withdraw(Date date,double amount)
{
    accumulation+=accumulate(date);
    balance-=amount;
    lastDate = date;
    total-=amount;
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"取出:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::settle(Date date)
{
    double settle = 0;
    if(date.getYear()>lastDate.getYear())
    {
        for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
        {
            accumulation+=accumulate(date);
            settle = accumulation/356*rate;
        }
    }
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"结算利息:"<<settle<<"元"<<endl;
    deposit(date,settle);
}
void SavingsAccount::show()
{
    Account::show();
}
CreditAccount::CreditAccount(int year,int month,int day,int id,double balance,double Credit,double Rate,double Fee): Account(id,balance),lastDate(year,month,day)
{
    credit=Credit;
    fee=Fee;
    rate=Rate;
    cout<<year<<"年"<<month<<"月"<<day<<"日";
    cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
double CreditAccount::getDebt(Date date)
{
    settle(date);
    return balance;
}
void CreditAccount::deposit(Date date,double amount)
{
    settle(date);
    if(credit<=0 || amount>credit)
    {
        date.show();
        cout<<"\t账户"<<id<<"\t信用卡可用额度不足!"<<endl;
    }
    else
    {
        balance-=amount;
        credit-=amount;
        date.show();
        cout<<"\t账户"<<id<<"\t信用卡已用额度:"<<amount<<"元"<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
        total-=amount;
    }
}
void CreditAccount::withdraw(Date date,double amount)
{
    settle(date);
    balance+=amount;
    if((credit+amount)<=10000)
    {
        credit=credit+amount;
    }
    else
    {
        credit=10000;
    }
    total+=amount;
    date.show();
    cout<<"\t账户"<<id<<"\t信用卡还款:"<<amount<<"元  "<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
}
void CreditAccount::settle(Date date)
{
    double settle=0;
    if((date.getMonth()<lastDate.getMonth())||(date.getYear()>lastDate.getYear()))
    {
        for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
        {
            settle+=fee;
        }
    }
    if(date.getDay()==1||date.getMonth()>lastDate.getMonth()||date.getYear()>lastDate.getYear())
    {
        if(date.getYear()==lastDate.getYear())
        {
            for(int j=1;j<=(date.getMonth()-lastDate.getMonth());j++)
            {
                for(int m=1;m<=lastDate-date;m++)
                {
                    settle-=balance*rate;
                }
            }
        }
        else
        {
            for(int j=1;j<=(date.getMonth()-lastDate.getMonth())+12;j++)
            {
                for(int m=1;m<=lastDate-date;m++)
                {
                    settle-=balance*rate;
                }
            }
        }
    }
    else
    {
        settle-=0;
    }
    balance-=settle;
    lastDate=date;
    total-=settle;
}
void CreditAccount::show()
{
    Account::show();
}

Account.h:

#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include"date.h"
class Account                      
{
protected:
    int id;
    double balance;
    static double total;
public:
    Account(int id, double balance);
    const int getId() {return id;}
    const double getBalance() {return balance;}
    static void getTotal();
    virtual void deposit(Date date,double amount)=0;
    virtual void withdraw(Date date,double amount)=0;
    virtual void settle(Date date)=0;
    virtual void show();
};
class SavingsAccount:public Account    
{
protected:
    double rate;    
    Date lastDate;
    double accumulation=0;
    const double accumulate(Date date);
public:
    SavingsAccount(int year,int month,int day,int id,double balance,double rate);
    void deposit(Date date,double amount);
    void withdraw(Date date,double amount);
    void settle(Date date);
    const double getRate() {return rate;}
    void show();
};
class CreditAccount:public Account
{
protected:
    double credit;
    double rate;
    double fee;
    Date lastDate;
public:
    CreditAccount(int year,int month,int day,int id,double balance,double credit,double rate,double fee);
    double getAvailableCredit() {return credit;}
    void deposit(Date date,double amount);
    void withdraw(Date date,double amount);
    double getDebt(Date date);
    void settle(Date date);
    void show();
};
#endif // ACCOUNT_H_INCLUDED

Account.cpp:

#include<iostream>
#include "account.h"
using namespace std;
Account::Account(int Id,double Balance)
{
    id=Id;
    balance=Balance;
}
void Account::show()
{
    cout<<"\t账号:"<<getId()<<"\t\t余额:"<<getBalance()<<"元"<<endl;
}
void Account::getTotal()
{
    cout<<"\t所有账户总金额:"<<total<<"元"<<endl;
}
SavingsAccount::SavingsAccount(int year,int month,int day,int id,double balance,double Rate):Account(id,balance),lastDate(year,month,day)
{
    rate=Rate;
    cout<<year<<"年"<<month<<"月"<<day<<"日";
    cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
const double SavingsAccount::accumulate(Date date)
{
    return (lastDate-date)*balance;
}
void SavingsAccount::deposit(Date date,double amount)
{
    accumulation+=accumulate(date);
    balance+=amount;
    lastDate = date;
    total+=amount;
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"存入:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::withdraw(Date date,double amount)
{
    accumulation+=accumulate(date);
    balance-=amount;
    lastDate = date;
    total-=amount;
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"取出:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::settle(Date date)
{
    double settle = 0;
    if(date.getYear()>lastDate.getYear())
    {
        for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
        {
            accumulation+=accumulate(date);
            settle = accumulation/356*rate;
        }
    }
    cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
    cout<<"\t账户"<<id<<"结算利息:"<<settle<<"元"<<endl;
    deposit(date,settle);
}
void SavingsAccount::show()
{
    Account::show();
}
CreditAccount::CreditAccount(int year,int month,int day,int id,double balance,double Credit,double Rate,double Fee): Account(id,balance),lastDate(year,month,day)
{
    credit=Credit;
    fee=Fee;
    rate=Rate;
    cout<<year<<"年"<<month<<"月"<<day<<"日";
    cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
double CreditAccount::getDebt(Date date)
{
    settle(date);
    return balance;
}
void CreditAccount::deposit(Date date,double amount)
{
    settle(date);
    if(credit<=0 || amount>credit)
    {
        date.show();
        cout<<"\t账户"<<id<<"\t信用卡可用额度不足!"<<endl;
    }
    else
    {
        balance-=amount;
        credit-=amount;
        date.show();
        cout<<"\t账户"<<id<<"\t信用卡已用额度:"<<amount<<"元"<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
        total-=amount;
    }
}
void CreditAccount::withdraw(Date date,double amount)
{
    settle(date);
    balance+=amount;
    if((credit+amount)<=10000)
    {
        credit=credit+amount;
    }
    else
    {
        credit=10000;
    }
    total+=amount;
    date.show();
    cout<<"\t账户"<<id<<"\t信用卡还款:"<<amount<<"元  "<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
}
void CreditAccount::settle(Date date)
{
    double settle=0;
    if((date.getMonth()<lastDate.getMonth())||(date.getYear()>lastDate.getYear()))
    {
        for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
        {
            settle+=fee;
        }
    }
    if(date.getDay()==1||date.getMonth()>lastDate.getMonth()||date.getYear()>lastDate.getYear())
    {
        if(date.getYear()==lastDate.getYear())
        {
            for(int j=1;j<=(date.getMonth()-lastDate.getMonth());j++)
            {
                for(int m=1;m<=lastDate-date;m++)
                {
                    settle-=balance*rate;
                }
            }
        }
        else
        {
            for(int j=1;j<=(date.getMonth()-lastDate.getMonth())+12;j++)
            {
                for(int m=1;m<=lastDate-date;m++)
                {
                    settle-=balance*rate;
                }
            }
        }
    }
    else
    {
        settle-=0;
    }
    balance-=settle;
    lastDate=date;
    total-=settle;
}
void CreditAccount::show()
{
    Account::show();
}

Date.h:

#ifndef DATE_H_INCLUDED
#define DATE_H_INCLUDED
class  Date
{
    int  year, month, day;
    int  totalDays;
public:
    Date(int year, int month, int day);
    int  getYear() const { return year; }
    int  getMonth() const { return month; }
    int  getDay() const { return day; }
    void  show() const;
    bool  isLeapYear(int year) const;
    int operator-(const Date &date) const {return date.totalDays-totalDays;}
};
#endif // DATE_H_INCLUDED

Date.cpp:

#include<iostream>
#include "date.h"
using namespace std;
Date::Date(int Year, int Month, int Day)
{
    year=Year;
    month=Month;
    day=Day;
    int Days=0;
    for(int i=0;i<year;i++)
    {
        if(isLeapYear(i)==true)
            Days=Days+366;
        else
            Days=Days+365;
    }
    switch(month){
    case 1:Days+=0;break;
    case 2:Days+=31;break;
    case 3:Days+=59;break;
    case 4:Days+=90;break;
    case 5:Days+=120;break;
    case 6:Days+=151;break;
    case 7:Days+=181;break;
    case 8:Days+=212;break;
    case 9:Days+=243;break;
    case 10:Days+=273;break;
    case 11:Days+=304;break;
    case 12:Days+=334;break;
    default:cout<<"month error!"<<endl;
    }
    totalDays=Days+day;
}
void  Date::show() const
{
    cout<<getYear()<<"年"<<getMonth()<<"月"<<getDay()<<"日";
}
bool  Date::isLeapYear(int year) const
{
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        return true;
    else
        return false;
}

运行截图:
在这里插入图片描述
学习掌握

动态联编,即是系统在运行时动态实现某个动作。而动态联编就是通过虚函数来实现的,因此学习了虚函数的定义以及使用方法及注意点,比如就要确保虚函数再定义时,参数表要与原先的保持完全一致。

具有虚函数的类就是抽象类,如果在抽象类的派生类中没有重新说明纯虚函数,则该函数在派生类中仍然为纯虚函数,而这个派生类仍然还是一个抽象类。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值