以下是3道难度递增的Java类与对象练习题,涵盖基础使用、封装特性和对象交互,每道题均包含解题思路、完整代码和输出结果:
练习题1:基础难度 - 定义学生类并使用
题目:定义一个Student
类,包含姓名(name
)、年龄(age
)、成绩(score
)三个属性,以及打印学生信息的方法。创建两个学生对象,分别赋值并调用方法打印信息。
解题思路
- 定义
Student
类,声明name
(String
)、age
(int
)、score
(double
)三个成员变量。 - 定义无参构造方法(可选,若不定义Java会默认生成)。
- 定义
printInfo()
方法,用于打印学生的姓名、年龄和成绩。 - 在
main
方法中创建两个Student
对象,通过.
操作符给属性赋值,调用printInfo()
输出信息。
代码实现
// 定义Student类
class Student {
// 成员变量
String name; // 姓名
int age; // 年龄
double score; // 成绩
// 打印学生信息的方法
public void printInfo() {
System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
}
}
// 测试类
public class TestStudent {
public static void main(String[] args) {
// 创建第一个学生对象
Student s1 = new Student();
s1.name = "张三";
s1.age = 18;
s1.score = 90.5;
s1.printInfo(); // 调用方法打印信息
// 创建第二个学生对象
Student s2 = new Student();
s2.name = "李四";
s2.age = 19;
s2.score = 88.0;
s2.printInfo();
}
}
输出结果
姓名:张三,年龄:18,成绩:90.5
姓名:李四,年龄:19,成绩:88.0
练习题2:中等难度 - 封装图书类
题目:定义一个Book
类,封装书名(title
)、作者(author
)、价格(price
)三个属性(用private
修饰),要求:
- 价格必须≥0,若赋值为负数则默认设为0。
- 提供
getter
和setter
方法操作属性。 - 提供有参构造方法,创建对象时直接赋值。
- 定义
show()
方法,打印图书完整信息。
解题思路
- 用
private
修饰title
、author
、price
,确保属性不能被直接访问。 - 为每个属性编写
getter
方法(获取值)和setter
方法(设置值),在price
的setter
中添加校验逻辑(若为负数则设为0)。 - 定义有参构造方法
Book(String title, String author, double price)
,通过setter
方法给属性赋值(复用校验逻辑)。 - 定义
show()
方法,调用getter
获取属性值并打印。 - 在
main
方法中创建Book
对象,测试正常赋值和异常赋值(如负价格)的效果。
代码实现
// 封装的Book类
class Book {
// 私有成员变量
private String title; // 书名
private String author; // 作者
private double price; // 价格
// 有参构造方法(通过setter赋值,触发校验)
public Book(String title, String author, double price) {
setTitle(title);
setAuthor(author);
setPrice(price);
}
// title的getter和setter
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
// author的getter和setter
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
// price的getter和setter(含校验)
public double getPrice() {
return price;
}
public void setPrice(double price) {
// 价格不能为负数,否则设为0
if (price < 0) {
this.price = 0;
} else {
this.price = price;
}
}
// 打印图书信息
public void show() {
System.out.println("书名:《" + getTitle() + "》,作者:" + getAuthor() + ",价格:" + getPrice() + "元");
}
}
// 测试类
public class TestBook {
public static void main(String[] args) {
// 创建正常价格的图书
Book book1 = new Book("Java编程思想", "Bruce Eckel", 108.0);
book1.show(); // 输出正常价格
// 创建负价格的图书(会被自动修正为0)
Book book2 = new Book("无效图书", "未知作者", -50.0);
book2.show();
// 测试通过setter修改价格
book2.setPrice(30.0); // 修改为正数
book2.show();
book2.setPrice(-10); // 再次尝试负数
book2.show();
}
}
输出结果
书名:《Java编程思想》,作者:Bruce Eckel,价格:108.0元
书名:《无效图书》,作者:未知作者,价格:0.0元
书名:《无效图书》,作者:未知作者,价格:30.0元
书名:《无效图书》,作者:未知作者,价格:0.0元
练习题3:进阶难度 - 银行账户类的交互
题目:定义一个BankAccount
类,模拟银行账户功能:
- 属性:账号(
accountId
,String
)、余额(balance
,double
,私有)。 - 方法:
- 构造方法:初始化账号和初始余额(余额≥0)。
deposit(double amount)
:存款(amount
≥0,否则存款失败)。withdraw(double amount)
:取款(amount
≥0且≤余额,否则取款失败)。getBalance()
:获取当前余额。transfer(BankAccount target, double amount)
:转账给另一个账户(当前账户取款,目标账户存款,需同时满足取款和存款条件)。
- 创建两个账户,测试存款、取款、转账功能。
解题思路
- 封装
balance
为私有属性,通过getBalance()
获取余额。 - 构造方法中校验初始余额,若为负数则设为0。
deposit
方法:校验amount
≥0,否则提示失败;成功则余额增加。withdraw
方法:校验amount
≥0且≤余额,否则提示失败;成功则余额减少。transfer
方法:调用当前账户的withdraw
和目标账户的deposit
,两者都成功则转账成功,否则失败。- 在
main
方法中创建两个账户,模拟存款、取款、转账场景(包括正常和异常情况)。
代码实现
// 银行账户类
class BankAccount {
private String accountId; // 账号
private double balance; // 余额(私有)
// 构造方法:初始化账号和初始余额
public BankAccount(String accountId, double initialBalance) {
this.accountId = accountId;
// 初始余额不能为负
if (initialBalance < 0) {
this.balance = 0;
System.out.println("账号" + accountId + "初始余额为负数,已设为0元");
} else {
this.balance = initialBalance;
}
}
// 存款
public void deposit(double amount) {
if (amount < 0) {
System.out.println("存款失败:金额不能为负数");
return;
}
balance += amount;
System.out.println("账号" + accountId + "存款" + amount + "元,当前余额:" + balance + "元");
}
// 取款
public void withdraw(double amount) {
if (amount < 0) {
System.out.println("取款失败:金额不能为负数");
return;
}
if (amount > balance) {
System.out.println("取款失败:余额不足,当前余额:" + balance + "元");
return;
}
balance -= amount;
System.out.println("账号" + accountId + "取款" + amount + "元,当前余额:" + balance + "元");
}
// 获取余额
public double getBalance() {
return balance;
}
// 转账给目标账户
public void transfer(BankAccount target, double amount) {
System.out.println("\n开始从" + accountId + "向" + target.accountId + "转账" + amount + "元...");
// 先尝试取款
if (amount < 0) {
System.out.println("转账失败:金额不能为负数");
return;
}
if (amount > this.balance) {
System.out.println("转账失败:余额不足,当前余额:" + this.balance + "元");
return;
}
// 取款成功后存款
this.withdraw(amount); // 从当前账户取款
target.deposit(amount); // 向目标账户存款
System.out.println("转账成功!");
}
}
// 测试类
public class TestBankAccount {
public static void main(String[] args) {
// 创建两个账户
BankAccount acc1 = new BankAccount("622202123456789", 1000); // 初始1000元
BankAccount acc2 = new BankAccount("622202987654321", -200); // 初始负余额(被修正为0)
// 测试存款
acc1.deposit(500); // 正常存款
acc1.deposit(-100); // 异常存款(负数)
// 测试取款
acc1.withdraw(300); // 正常取款
acc1.withdraw(2000); // 异常取款(余额不足)
// 测试转账
acc1.transfer(acc2, 400); // 正常转账
acc1.transfer(acc2, 1000); // 异常转账(余额不足)
// 打印最终余额
System.out.println("\n最终余额:");
System.out.println(acc1.getAccountId() + ":" + acc1.getBalance() + "元");
System.out.println(acc2.getAccountId() + ":" + acc2.getBalance() + "元");
}
}
// 为了在测试类中获取accountId,添加getter(实际开发中可根据需求开放)
class BankAccount {
// ... 其他代码不变 ...
public String getAccountId() {
return accountId;
}
}
输出结果
账号622202987654321初始余额为负数,已设为0元
账号622202123456789存款500.0元,当前余额:1500.0元
存款失败:金额不能为负数
账号622202123456789取款300.0元,当前余额:1200.0元
取款失败:余额不足,当前余额:1200.0元
开始从622202123456789向622202987654321转账400.0元...
账号622202123456789取款400.0元,当前余额:800.0元
账号622202987654321存款400.0元,当前余额:400.0元
转账成功!
开始从622202123456789向622202987654321转账1000.0元...
转账失败:余额不足,当前余额:800.0元
最终余额:
622202123456789:800.0元
622202987654321:400.0元
总结
- 练习题1掌握类的基本定义、对象创建和属性/方法调用。
- 练习题2理解封装的核心(私有属性+getter/setter)及数据校验逻辑。
- 练习题3实现对象间的交互(转账涉及两个账户的协作),强化封装和方法设计。
通过这三道题,可逐步掌握类与对象的核心用法,从基础语法过渡到实际场景应用。