一.题目:
二.代码:
实现代码:
import java.util.Date;
//银行账户类
class Account{
public String accountid;
public String name;
public double balance;
public Date creatTime;
public Account(String accountid,String name, double balance){
this.accountid=accountid;
this.name=name;
this.balance=balance;
this.creatTime=new Date();//使用系统时间作为账户建立时间。
}
//存款
public void deposit(double amount){
balance=balance+amount;
}
//取款
public void withdraw(double amount){
if(balance>=amount)
balance=balance-amount;
else
System.out.println("余额不足!");
}
//转账
public void transfer(Account receiver,double amount){
if(balance>=amount)
{
balance=balance-amount;
receiver.deposit(amount);
System.out.println("转账成功!");
}
else{
System.out.println("余额不足,转账失败!");
}
}
//查询余额
public double getBalance(){
return balance;
}
}
//定期账户类
class FixedTermAccount extends Account{
private int term;
public FixedTermAccount(String accountid,String name,double balance,int term){
super(accountid,name,balance);
this.term=term;
}
//重写取款方法
public void withdraw(double amount){
Date now=new Date();
long diff=now.getTime()-this.creatTime.getTime();//获取账户建立时间到现在的时间差
long days=diff/(1000*60*60*24);//转换为天数
if (days>=term*365) {
super.withdraw(amount);//到期才能取钱
}
else{
System.out.println("定期账户未到期,不能取款!");
}
}
}
//信用卡账户类
class CreatitCardAccount extends Account{
private double overdraft;
public CreatitCardAccount(String accountid,String name,double balance ,double overdraft){
super(accountid,name,balance);
this.overdraft=overdraft;
}
//重写取款方法
public void withdraw(double amount){
if(balance+overdraft>=amount){//考虑透支额度
balance=balance-amount;
}
else{
System.out.println("超出信用额度,取款失败");
}
}
//重写转账方法
public void transfer(Account receiver ,double amount){
System.out.println("信用卡账户不能进行转账!");
}
}
测试代码:
public class AccountManager{
public static void main(String[] args){
//创立两个用户
Account account1=new Account("001","张三",1000);
Account account2=new Account("002","李四",300);
//分别存入500元
account1.deposit(500);
account2.deposit(500);
//张三取出200元
account1.withdraw(200);
//张三给李四300元
account1.transfer(account2,300);
//显示余额
System.out.println("张三的余额:"+account1.getBalance());
System.out.println("李四的余额:"+account2.getBalance());
//创建定期账户和信用卡账户进行操作
FixedTermAccount count1=new FixedTermAccount("001","张三",3000,3);
CreatitCardAccount count2=new CreatitCardAccount("002","李四",4000,10000);
count1.withdraw(200);//测试count1取钱200元
count1.withdraw(3000);//测试count1取钱3000元
count1.deposit(5000);//测试count1存钱5000元
count2.withdraw(12000);//测试count2取钱12000元
count2.withdraw(20000);//测试count2取钱20000元
count2.deposit(6000);//测试count2存钱6000元
count2.withdraw(20000);//测试count2取钱20000元;
}
}
输出:
三.解释:
实现代码:
第1行
import java.util.Date;
在Java中,import java.util.Date; 语句的作用是导入 java.util 包中的 Date 类,这样你就可以在你的代码中使用 Date 类而不需要每次都写出完整的类名 java.util.Date。
Date
类是Java的一个核心类,用于表示特定的瞬间,精确到毫秒。这个类通常用于表示日期和时间,特别是在没有更高级的日期和时间API可用时。
当你导入 Date
类后,你可以在你的代码中创建 Date
对象,比如用于记录某个事件发生的时间,或者用于比较两个日期等。
import java.util.Date;
public class Example {
public static void main(String[] args) {
// 创建一个表示当前日期和时间的Date对象
Date now = new Date();
// 输出当前日期和时间
System.out.println("Current date and time: " + now);
// 创建一个表示特定日期和时间的Date对象
Date specificDate = new Date(123456789000L); // 这里的数字是毫秒数,表示从1970年1月1日00:00:00 GMT开始的毫秒数
// 输出特定日期和时间
System.out.println("Specific date and time: " + specificDate);
}
}
在这个例子中,我们导入了 Date
类,并创建了两个 Date
对象:一个表示当前的日期和时间,另一个表示一个特定的日期和时间(通过传递一个长整型的毫秒数给 Date
构造函数)。
然而,值得注意的是,从Java 8开始,引入了新的日期和时间API(java.time
包),它提供了更强大、更灵活且类型安全的日期和时间处理功能。因此,在大多数现代Java应用中,你可能会更倾向于使用 java.time
包中的类,比如 LocalDate
、LocalTime
、LocalDateTime
等,而不是 java.util.Date
。但 Date
类仍然在某些旧的代码库和API中被广泛使用。
第3~7行
class Account{
public String accountid;
public String name;
public double balance;
public Date creatTime;
定义了Account类,然后没有封装属性,用了public来公开属性。
所有这四个字段都是 public
的,这意味着它们可以从类的外部直接访问和修改。然而,这种设计通常不被推荐,因为它破坏了封装性,这是面向对象编程的一个基本原则。封装性意味着隐藏对象的内部状态(即字段的值)并仅通过公共方法来访问和修改这些值。这有助于保护数据的完整性和安全性,并提供更清晰、更易于维护的代码。
这个 Account
类是一个简单的Java类,用于表示银行账户。然而,由于所有字段都是公共的,它违反了封装性的原则。为了改进这个类,应该将这些字段设置为 private
private String accountid;
private String name;
private double balance;
private LocalDateTime createTime; // 修正拼写错误,并使用LocalDateTime
第9-12行
public Account(String accountid,String name, double balance){
this.accountid=accountid;
this.name=name;
this.balance=balance;
初始化属性
第13行
this.creatTime=new Date();//使用系统时间作为账户建立时间。
- 这行代码创建了一个新的
Date
对象(来自java.util
包),该对象表示构造方法被调用时的系统当前时间,并将这个Date
对象赋值给当前对象的creatTime
属性。这行代码实际上是在记录账户创建的时间。
第16-18行
public void deposit(double amount){
balance=balance+amount;
}
这段代码是Java语言中的一个方法定义,用于描述一个deposit(存钱)
操作,通常用于银行账户或类似的金融应用中。下面是对这段代码的详细解释:
方法定义
public
: 这是一个访问修饰符,它表明这个方法可以从任何其他类中被访问。void
: 这表明该方法没有返回值。deposit
: 这是方法的名称,表示这是一个存款方法。(double amount)
: 这是方法的参数列表。它接受一个double
类型的参数amount
,代表要存入的金额。
方法体
balance=balance+amount;
: 这是方法体中的唯一一条语句。它表示将当前的balance
(账户余额)与传入的amount
(存款金额)相加,并将结果赋值回balance
。这样,balance
就被更新为新的余额了。
第20-15行
public void withdraw(double amount){
if(balance>=amount)
balance=balance-amount;
else
System.out.println("余额不足!");
}
这段代码定义了一个withdraw(取款)
方法,用于从银行账户中提取指定金额的资金。以下是对该方法的详细解释:
方法定义
public
: 方法的访问修饰符,表示该方法可以从任何其他类中被访问。void
: 表示该方法没有返回值。withdraw
: 方法的名称,表示取款操作。(double amount)
: 方法的参数,一个double
类型的amount
,表示要提取的金额。
方法体
if(balance>=amount)
: 这是一个条件判断语句,它检查当前的账户余额balance
是否大于或等于要提取的金额amount
。balance=balance-amount;
: 如果余额足够(即balance >= amount
),则从余额中减去提取的金额,更新账户余额。
else
: 如果余额不足(即balance < amount
),则执行下面的语句。System.out.println("余额不足!");
: 在控制台上打印一条消息,告知用户余额不足,无法提取所请求的金额。
第27-37行
public void transfer(Account receiver,double amount){
if(balance>=amount)
{
balance=balance-amount;
receiver.deposit(amount);
System.out.println("转账成功!");
}
else{
System.out.println("余额不足,转账失败!");
}
}
这段代码定义了一个transfer
方法,用于从当前账户向另一个账户(receiver
)转账指定金额(amount
)。下面是对该方法的详细解释:
方法定义
public
: 方法的访问修饰符,表示该方法可以从任何其他类中被访问。void
: 表示该方法没有返回值。transfer
: 方法的名称,表示转账操作。(Account receiver, double amount)
: 方法的参数列表,包括两个参数:Account receiver
: 一个类型为Account
的对象,表示接收转账的账户。double amount
: 一个double
类型的值,表示要转账的金额。
方法体
if(balance>=amount)
: 这是一个条件判断语句,它检查当前账户的余额balance
是否大于或等于要转账的金额amount
。balance=balance-amount;
: 如果余额足够(即balance >= amount
),则从当前账户的余额中减去转账的金额。receiver.deposit(amount);
: 将要转账的金额存入接收账户(receiver
)。这里假设Account
类有一个deposit
方法用于存款。System.out.println("转账成功!");
: 在控制台上打印一条消息,告知用户转账成功。
else
: 如果余额不足(即balance < amount
),则执行下面的语句。System.out.println("余额不足,转账失败!");
: 在控制台上打印一条消息,告知用户由于余额不足,转账失败。
第39-41行
public double getBalance(){
return balance;
}
这段代码定义了一个名为getBalance
的公共方法,它返回当前账户的余额。下面是该方法的详细解释:
方法定义
public
: 这是一个访问修饰符,表示这个方法可以从任何其他类中被访问。double
: 这是方法的返回类型,表示这个方法将返回一个double
类型的值。getBalance
: 这是方法的名称,它遵循了Java中常见的命名约定,即使用“get”前缀来命名返回某个属性值的访问器方法。()
: 这是方法的参数列表,括号内为空表示这个方法没有参数。
方法体
return balance;
: 这是方法的返回语句,它返回balance
变量的当前值。balance
是假设在Account
类中定义的一个私有成员变量,用来存储账户的余额。
第44行
class FixedTermAccount extends Account{
FixedTermAccount extends Account
这段代码表示FixedTermAccount
类是从Account
类继承而来的。在Java中,继承是面向对象编程的一个核心概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性和方法。
在这个例子中,FixedTermAccount
是子类,Account
是父类。FixedTermAccount
继承了Account
类中的所有公共(public
)和保护(protected
)属性和方法,这意味着FixedTermAccount
类的对象可以使用这些属性和方法,除非它们在FixedTermAccount
类中被覆盖(重写)。
第45行
private int term;
在FixedTermAccount
类中,如果你有一个私有成员变量term
,它可能用来表示账户的固定期限。这个term
变量可能以月、天或其他时间单位来衡量,具体取决于你的业务需求和系统设计。
第46-49行
public FixedTermAccount(String accountid,String name,double balance,int term){
super(accountid,name,balance);
this.term=term;
}
基本继承
注意super传递
第52-62行
public void withdraw(double amount){
Date now=new Date();
long diff=now.getTime()-this.creatTime.getTime();//获取账户建立时间到现在的时间差
long days=diff/(1000*60*60*24);//转换为天数
if (days>=term*365) {
super.withdraw(amount);//到期才能取钱
}
else{
System.out.println("定期账户未到期,不能取款!");
}
}
在你提供的withdraw
方法中,你尝试根据账户的建立时间和当前时间之间的差异来判断是否达到了固定期限(term
),从而决定是否允许取款。这里有几个问题需要注意:
-
creatTime
变量没有在代码中定义。它应该是一个Date
类型的成员变量,用于存储账户的建立时间。你需要确保在FixedTermAccount
类中定义了这个变量,并且在创建账户时对其进行了初始化。 -
term
变量被假设为以年为单位。但是,你的代码将term
直接与天数相乘(term*365
),这没有考虑到闰年的情况。一个更精确的方法是使用Calendar
类来计算具体的日期差异。 -
System.out.println
用于输出错误信息到控制台。在实际应用中,更好的做法可能是抛出一个异常或者返回一个错误信息给调用者,以便调用者可以适当地处理这种情况。
第66-71行
class CreatitCardAccount extends Account{
private double overdraft;
public CreatitCardAccount(String accountid,String name,double balance ,double overdraft){
super(accountid,name,balance);
this.overdraft=overdraft;
}
这一行定义了一个公共的构造方法,用于创建CreatitCardAccount
对象。构造方法的名字与类名相同,它没有返回值(返回类型为void
)。
- 构造方法接受四个参数:
accountid
(账户ID),name
(账户名),balance
(账户余额),和overdraft
(透支额度)。 super(accountid, name, balance);
:这一行调用了父类Account
的构造方法,并将accountid
,name
和balance
作为参数传递给它。这是子类构造方法调用父类构造方法的常见方式,以确保父类中的属性和方法被正确初始化。this.overdraft = overdraft;
:这一行将构造方法参数中的overdraft
值赋给类的overdraft
属性。this
关键字用于引用当前对象的属性和方法,以避免与参数名或局部变量名冲突。
需要注意的是,代码中有一个小错误:类名CreatitCardAccount
可能是CreditCardAccount
的拼写错误。在实际编程中,应该使用正确的拼写和命名规范来避免混淆和错误。
另外,从这段代码中我们不能看到Account
类的具体实现,但可以推测Account
类至少有一个接受accountid
、name
和balance
作为参数的构造方法。
第74-82行
public void withdraw(double amount){
if(balance+overdraft>=amount){//考虑透支额度
balance=balance-amount;
}
else{
System.out.println("超出信用额度,取款失败");
}
}
withdraw
方法,这个方法用于从账户中取款。
-
public void withdraw(double amount)
: 这是一个公共方法,名为withdraw
,它接受一个double
类型的参数amount
,表示要取款的金额。方法没有返回值,所以返回类型为void
。 -
if(balance+overdraft>=amount)
: 这是一个条件判断语句。它检查当前账户的余额(balance
)加上透支额度(overdraft
)是否大于或等于要取款的金额(amount
)。如果是这样,说明账户有足够的资金(包括透支额度)来支持这次取款。 -
balance=balance-amount;
: 如果上面的条件成立,这行代码会从账户的余额中减去取款的金额。这样,账户的余额就会减少相应的金额。 -
else
: 如果上述条件不成立,即账户余额加上透支额度仍然不足以支持取款,那么会执行else
块中的代码。 -
System.out.println("超出信用额度,取款失败");
: 这行代码会在控制台上输出一条消息,告诉用户因为超出了信用额度,所以取款失败。
第84-87行
public void transfer(Account receiver ,double amount){
System.out.println("信用卡账户不能进行转账!");
}
}
在您提供的transfer
方法中,您直接输出了一条消息,说明“信用卡账户不能进行转账!”。这意味着您有意地让这个transfer
方法不做任何实际的转账操作,而是直接通知用户信用卡账户不支持转账功能。
在实际应用中,这种设计可能是基于业务规则或安全考虑的。信用卡账户通常不允许直接转账到其他账户,因为信用卡的主要用途是消费和透支,而不是作为资金转移的工具。然而,具体是否允许转账还取决于具体的银行业务规则和系统设计。
测试代码:
public class AccountManager{
public static void main(String[] args){
//创立两个用户
Account account1=new Account("001","张三",1000);
Account account2=new Account("002","李四",300);
//分别存入500元
account1.deposit(500);
account2.deposit(500);
//张三取出200元
account1.withdraw(200);
//张三给李四300元
account1.transfer(account2,300);
//显示余额
System.out.println("张三的余额:"+account1.getBalance());
System.out.println("李四的余额:"+account2.getBalance());
//创建定期账户和信用卡账户进行操作
FixedTermAccount count1=new FixedTermAccount("001","张三",3000,3);
CreatitCardAccount count2=new CreatitCardAccount("002","李四",4000,10000);
count1.withdraw(200);//测试count1取钱200元
count1.withdraw(3000);//测试count1取钱3000元
count1.deposit(5000);//测试count1存钱5000元
count2.withdraw(12000);//测试count2取钱12000元
count2.withdraw(20000);//测试count2取钱20000元
count2.deposit(6000);//测试count2存钱6000元
count2.withdraw(20000);//测试count2取钱20000元;
}
}