关联与继承练习题
题目:
创建一个银行账户的继承层次,表示银行的所有客户的账户。每个客户都能在他们的银行账户存钱,取钱。但是账户可以分为更具体的两种类型,例如,依靠存款生息的存储账户SavingsAccount类,另一种就是信用卡账户CheckingAccount(没有利息但可以透支一定的金额)。每个账户的每次交易都需要存储以方便用来查询。每个客户可以拥有很多不同id的银行账户。
【任务一】根据设计出的UML图,回答问题
(1). Person和Account之间是什么关系?
Person与Account是关联关系。一个用户可以持有多个账户,且用户与账户相对独立
(2). Account和Transaction之间是什么关系?
Account与Transaction是依赖关系。因为Transaction是由Account构造出来的。只有Account存在的情况下,Transaction才存在
(3). SavingsAccount和CheckingAccount和Account之间是什么关系?
继承关系,SavingsAccount和CheckingAccount是Account的继承
【任务二】根据设计图和运行结果,设计出每个类的代码。测试程序的主要代码已经给出,请补充部分方法。
public class TestAccount {
public static void main (String[] args) {
Person p = new Person(“George”);
//创建一个储蓄账户account1
SavingsAccount account1 = new SavingsAccount(p.getName(),1122, 1000);
SavingsAccount.setAnnualInterestRate(5.5);
//创建一个和account1相同id的储蓄账户
SavingsAccount account2 = new SavingsAccount(p.getName(),1122, 1000);
//创建一个信用卡账户account3
CheckingAccount account3 = new CheckingAccount(p.getName(),2233,0, 20000);
//加入account1
p.addAcouunt(account1);
//一个人不能拥有相同的id的账户,account2不能加入成功
p.addAcouunt(account2);
//加入account3
p.addAcouunt(account3);
//在Person类中定printAllAccounts方法并补充完整
p.printAllAccounts();
account1.deposit(30);
account1.deposit(40);
account1.deposit(50);
account1.withdraw(5);
account1.withdraw(4);
account1.withdraw(2);
//在测试类中定义printAllTrans方法,并补充完整
printAllTrans(account1);
account3.withdraw(3000);
account3.withdraw(4000);
account3.withdraw(5000);
account3.withdraw(8000);
printAllTrans(account3);
}
public static void printAllTrans(Account a){
//补充代码
}
}
}
源码:
Account(账户)类:
import java.util.ArrayList;
//CheckingAccount与SavingsAccount的父类
public class Account {
//存储人的姓名
private String personName;
//卡号
private int carId;
//存储金额
private int balance;
//用于存储账户所有的交易信息
private ArrayList<Transaction> transactions = new ArrayList<>();
Account(String personName,int carId,int balance){
this.personName = personName;
this.carId = carId;
this.balance = balance;
}
//用于存取CheckingAccount传入的参数
Account(String personName,int carId){
this.personName = personName;
this.carId = carId;
}
//传入金额
public void setBalance(int balance) {
this.balance = balance;
}
//获取卡号
public int getCarId(){
return carId;
}
//获取用户名
public String getPersonName() {
return personName;
}
//获取卡内余额
public int getBalance() {
return balance;
}
//向订单容器内添加订单
public void addTran(Transaction transaction){
transactions.add(transaction);
}
//获取订单容器
public ArrayList<Transaction> getTransactions() {
return transactions;
}
}
CheckingAccount(信用卡)类:
public class CheckingAccount extends Account {
//可借额度
private int borrowableAmount;
//已借额度
private int haveBorrowableAmount;
//构造函数
CheckingAccount(String personName,int carId,int haveBorrowableAmount,int borrowableAmount){
super(personName,carId);
this.haveBorrowableAmount = haveBorrowableAmount;
this.borrowableAmount = borrowableAmount;
}
@Override
public String toString() {
return ("卡的类别:CheckingAccount" + " 卡号:" + super.getCarId() + " 可借额度" +
this.borrowableAmount + " 已借额度" + this.haveBorrowableAmount);
}
//还款
public void deposit(int money){
if(haveBorrowableAmount<money){
System.out.println("还款金额大于欠款金额,还款失败");
System.out.println("当前欠款金额为:" + haveBorrowableAmount);
}
haveBorrowableAmount -=money;
borrowableAmount +=money;
addTran(new Transaction(getCarId(),'D',money,haveBorrowableAmount,borrowableAmount));
}
//借款
public void withdraw(int money){
if(borrowableAmount<money){
System.out.println("卡号为:"+getCarId() + "的可用余额不足,借款失败");
return;
}
borrowableAmount -=money;
haveBorrowableAmount+=money;
addTran(new Transaction(getCarId(),'W',money,haveBorrowableAmount,borrowableAmount));
}
}
SavingsAccount(借记卡)类:
public class SavingsAccount extends Account {
private static double AnnualInterestRate;
SavingsAccount(String personName,int carId,int balance){
super(personName,carId,balance);
}
public static void setAnnualInterestRate(double AnnualInteresRate){
AnnualInterestRate = AnnualInteresRate;
}
public String toString(){
return ("卡的类别:SavingsAccount" + " 卡号为:" + super.getCarId()
+" 用户余额为:" + super.getBalance() + " 年利率为:" + AnnualInterestRate+ "%");
}
public void deposit(int money){
super.setBalance(money+getBalance());
addTran(new Transaction(getCarId(),'D',money,super.getBalance()));
}
public void withdraw(int money){
super.setBalance(getBalance()-money);
addTran(new Transaction(getCarId(),'W',money,super.getBalance()));
}
}
Person(用户)类:
import java.util.ArrayList;
public class Person {
private String name;
private ArrayList<Account> accounts = new ArrayList<>();
Person(String name){
this.name = name;
}
public String getName(){
return name;
}
public void addAccount(Account account){
boolean flag = true;
for(Account a1:accounts){
if(a1.getCarId() == account.getCarId()){
flag = false;
break;
}
}
if(flag){
accounts.add(account);
}else{
System.out.println(getName()+"已经拥有"+account.getCarId()+"的卡了,添加失败");
}
}
//打印用户所拥有的卡
public void printAllAccounts(){
for(Account account:accounts){
System.out.println(account.toString());
}
}
}
Transaction类:
import java.util.Date;
public class Transaction {
private Date tradTime;
private char tradType;
private double tradAmount;
private double balance;
private int carId;
private double haveBorrowableAmount;
//借记卡的构造函数
Transaction(int carId,char tradType, double tradAmount, double balance) {
tradTime = new Date();
this.tradType = tradType;
this.tradAmount = tradAmount;
this.balance = balance;
this.carId = carId;
}
//信用卡的构造函数
Transaction(int carId,char tradType, double tradAmount,double haveBorrowableAmount ,double balance) {
tradTime = new Date();
this.tradType = tradType;
this.tradAmount = tradAmount;
this.balance = balance;
this.haveBorrowableAmount = haveBorrowableAmount;
this.carId = carId;
}
//获取信用卡的已借额度
public double getHaveBorrowableAmount() {
return haveBorrowableAmount;
}
//获取借款时间
public Date getTradTime() {
return tradTime;
}
//获取借款类型
public char getTradType() {
return tradType;
}
//获取卡号
public int getCarId(){
return carId;
}
public double getTradAmount() {
return tradAmount;
}
public double getBalance() {
return balance;
}
public void print(Account a){
//判断传入的卡类,并根据卡类进行输出
if(a instanceof CheckingAccount){
System.out.printf("%-40s%-15s%-15s%-15s%-25s%-20s\n", getTradTime(),getCarId(),
getTradType(), getTradAmount(), getHaveBorrowableAmount(),getBalance());
}else{
System.out.printf("%-40s%-15s%-15s%-15s%-15s\n", getTradTime(),getCarId(),
getTradType(), getTradAmount(), getBalance());
}
}
}
TestAccount(测试类):
public class TestAccount {
public static void main (String[] args) {
Person p = new Person("George");
//创建一个储蓄账户account1
SavingsAccount account1 = new SavingsAccount(p.getName(),1122, 1000);
SavingsAccount.setAnnualInterestRate(5.5);
//创建一个和account1相同id的储蓄账户
SavingsAccount account2 = new SavingsAccount(p.getName(),1122, 1000);
//创建一个信用卡账户account3
CheckingAccount account3 = new CheckingAccount(p.getName(),2233,0, 20000);
//加入account1
p.addAccount(account1);
//一个人不能拥有相同的id的账户,account2不能加入成功
p.addAccount(account2);
//加入account3
p.addAccount(account3);
//在Person类中定printAllAccounts方法并补充完整
p.printAllAccounts();
account1.deposit(30);
account1.deposit(40);
account1.deposit(50);
account1.withdraw(5);
account1.withdraw(4);
account1.withdraw(2);
printAllTrans(account1);
account3.withdraw(3000);
account3.withdraw(4000);
account3.withdraw(5000);
account3.withdraw(8000);
account3.withdraw(500);
printAllTrans(account3);
}
public static void printAllTrans(Account a){
//判断传入的卡类,并根据卡类进行输出
if(a instanceof SavingsAccount){
System.out.printf("%-40s%-15s%-15s%-15s%-15s\n", "Date", "AccountId","Type", "Amount", "Balance");
}else{
System.out.printf("%-40s%-15s%-15s%-15s%-25s%-20s\n", "Date", "AccountId","Type", "Amount","haveBorrowableAmount","borrowableAmount");
}
for(Transaction t1:a.getTransactions()){
t1.print(a);
}
}
}
运行截图:
总结:
本题较为简单(如果不懂的话,可以看代码内的注释,很容易理解思路的)。主要的难点就是如何在订单输出的时候,使用一个方法输出两种不同的卡号,因为借记卡的信息是(交易时间,卡号,交易时间,账户余额),而信用卡的类型是(交易时间,卡号,交易类型,交易金额,已借金额,可借金额)。在这里我使用的是instanceof来判断传入的参数的类型,如果为SavingsAccount,则按借记卡的形式输出,如果为CheckingAccount,则按信用卡的形式输出。