mirror of
https://github.com/m1ngsama/code4sk.git
synced 2025-12-24 10:51:22 +00:00
649 lines
23 KiB
Text
649 lines
23 KiB
Text
//2023.06.28 Java期末复习课程
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
1.写出程序运行结果
|
||
class A{
|
||
public A(){
|
||
System.out.println("Hello!");
|
||
}
|
||
public A(String s){
|
||
this();
|
||
System.out.println("My name is"+s);
|
||
}
|
||
}
|
||
class B extends A{
|
||
public static void main(String[] args){
|
||
B b=new B("Amy");
|
||
}
|
||
public B(){
|
||
System.out.println("I am Amy.");
|
||
}
|
||
public B(String s){
|
||
super(s);
|
||
System.out.println("How are you!");
|
||
}
|
||
}
|
||
|
||
程序运行结果如下:
|
||
|
||
Hello!
|
||
My name is Amy
|
||
How are you!
|
||
|
||
首先,程序从B类的主方法开始执行。在主方法中,创建了一个B类的对象b,并调用了带有一个String类型参数的构造方法,参数为"Amy"。由于B类继承自A类,因此构造B类对象时会先调用父类A的构造方法。
|
||
|
||
在A类的构造方法中,首先打印输出"Hello!"。接着,B类的构造方法调用了父类A的带有一个String类型参数的构造方法,这里传入了"Amy"作为参数。在A类的带有一个String类型参数的构造方法中,先调用了A类的无参构造方法(this()),所以又会打印输出"Hello!"。然后,打印输出"My name is Amy"。
|
||
|
||
接着,回到B类的构造方法,继续执行后续的代码。在B类的构造方法中,打印输出"I am Amy."。最后,打印输出"How are you!"。
|
||
|
||
因此,程序运行结果为:
|
||
|
||
Hello!
|
||
My name is Amy
|
||
How are you!
|
||
|
||
|
||
*******************************************************************************************************
|
||
|
||
|
||
2.下列try catch语句块中的第二个语句S1将引起一个异常,试回答下列问题。
|
||
try{
|
||
S1;
|
||
S2;
|
||
}catch(ExceptionType1 e){
|
||
}catch(ExceptionType2 e){
|
||
}finally{
|
||
S3;
|
||
}
|
||
S4
|
||
(1)S2会执行吗?
|
||
(2)如果异常未被捕获,S3会被执行吗?S4会被执行吗?
|
||
(3)如果catch子句捕获了异常,S3会被执行吗?S4会被执行吗?
|
||
|
||
|
||
(1) S2不会执行。由于S1引发了异常,程序将会跳转到catch子句,而不会继续执行后面的语句。
|
||
(2) 如果异常未被捕获,S3会被执行。无论是否发生异常,finally块中的代码都会被执行。但是,S4不会被执行,因为异常发生后程序会跳出try-catch-finally语句块。
|
||
(3) 如果catch子句捕获了异常,S3会被执行。无论是否发生异常,finally块中的代码都会被执行。S4也会被执行,因为异常已经被处理并且程序会继续执行后面的语句。
|
||
|
||
如果异常未被捕获,程序会跳转到catch子句之前的位置,不会执行后面的语句,但finally块中的代码仍会被执行。
|
||
如果catch子句捕获了异常,程序会继续执行catch子句之后的语句,包括finally块中的代码。
|
||
|
||
|
||
|
||
*******************************************************************************************************
|
||
|
||
|
||
3.下列代码简单模拟了多个窗口购买火车票,会出现下图问题,请问代码如何修改?(提示:synchronized)
|
||
class BuyTicket implements Runnable{
|
||
int ticketnum=10;//共有十张宁波到北京的火车票
|
||
public void run{
|
||
for(int i=1;i<=20;i++){//每个窗口有20人在排队买票
|
||
if(ticketnum>0)//票数大于0,买票
|
||
System.out.println(Thread.currentThread().getName()+"买到从宁波到北京的第"+ticketnum--+"张车票");
|
||
}
|
||
}
|
||
}
|
||
public class Test{
|
||
public static void main(String[] args){
|
||
BuyTicket t=new BuyTicket();
|
||
Thread t1=new Thread(t,"1号窗口");
|
||
t1.start();
|
||
Thread t2=new Thread(t,"2号窗口");
|
||
t2.start();
|
||
Thread t3=new Thread(t,"3号窗口");
|
||
t3.start();
|
||
}
|
||
}
|
||
|
||
问题出在多个线程同时访问ticketnum变量时可能会出现竞争条件,导致数据不一致。为了解决这个问题,可以使用synchronized关键字来保证多个线程访问ticketnum变量时的同步性。
|
||
|
||
修改后的代码如下:
|
||
|
||
class BuyTicket implements Runnable{
|
||
private int ticketnum=10;//共有十张宁波到北京的火车票
|
||
|
||
public synchronized void run(){
|
||
for(int i=1;i<=20;i++){//每个窗口有20人在排队买票
|
||
if(ticketnum>0){//票数大于0,买票
|
||
System.out.println(Thread.currentThread().getName()+"买到从宁波到北京的第"+ticketnum--+"张车票");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public class Test{
|
||
public static void main(String[] args){
|
||
BuyTicket t=new BuyTicket();
|
||
Thread t1=new Thread(t,"1号窗口");
|
||
t1.start();
|
||
Thread t2=new Thread(t,"2号窗口");
|
||
t2.start();
|
||
Thread t3=new Thread(t,"3号窗口");
|
||
t3.start();
|
||
}
|
||
}
|
||
|
||
在BuyTicket类的run方法上加上synchronized关键字,这样就可以保证在多线程环境下只有一个线程能够访问run方法,从而避免了多个线程同时修改ticketnum的问题。这样可以保证每个窗口买票时的操作是互斥的,不会出现问题。
|
||
在BuyTicket类的run方法上添加了synchronized关键字,这样每个窗口在执行run方法时都会获得对象锁,保证了同一时间只有一个窗口在买票。这样就避免了多个窗口同时买同一张票的问题。
|
||
|
||
*******************************************************************************************************
|
||
|
||
|
||
4.阅读以下代码片段,回答问题
|
||
import java.awt.event.*;
|
||
import javax.swing.*;
|
||
import java.awt.*;
|
||
class EventTest extends JFrame implements ActionListener/*a*/{
|
||
JButton btn1,btn2;Container ctpn;
|
||
EventTest(){
|
||
ctpn=this.getContentPane();//b
|
||
btn1=new JButton("Blue");
|
||
btn2=new JButton("Red");
|
||
btn1.addActionListener(this);//c
|
||
btn2.addActionListener(this);
|
||
this.setTitle("Action Event");setSize(200,150);
|
||
this.setLayout(new FlowLayout(FlowLayout.CENTER)); //d
|
||
this.ctpn.add(btn1);ctpn.add(btn2);
|
||
this.setVisible(true);
|
||
}
|
||
public void actionPerformed(ActionEvent e){
|
||
JButton btn=(JButton)e.getSource();//e
|
||
if(btn==btn1) ctpn.setBackground(Color.blue);
|
||
if(btn==btn2)
|
||
ctpn.setBackground(Color.red);
|
||
}
|
||
public static void main(String args[]){
|
||
EventTest frm=new EventTest();
|
||
}
|
||
}
|
||
(1)在"//"后添加注释
|
||
(2)画出程序的运行效果,并说程序完成的功能
|
||
|
||
(1) 在"//"后添加注释:
|
||
|
||
import java.awt.event.*; // 导入事件相关的包
|
||
import javax.swing.*; // 导入Swing相关的包
|
||
import java.awt.*; // 导入AWT相关的包
|
||
|
||
class EventTest extends JFrame implements ActionListener{ //a 继承JFrame类,并实现ActionListener接口,ActionListener接口是一个事件监听器接口,用于处理按钮点击事件
|
||
|
||
JButton btn1,btn2; // 创建两个按钮对象
|
||
Container ctpn; // 创建一个容器对象
|
||
|
||
EventTest(){
|
||
ctpn=this.getContentPane();//b getContentPane()方法用于获取容器的内容面板。
|
||
btn1=new JButton("Blue"); // 创建名为"Blue"的按钮
|
||
btn2=new JButton("Red"); // 创建名为"Red"的按钮
|
||
btn1.addActionListener(this); //c 为按钮添加事件监听器,addActionListener(this)方法将当前类实例作为按钮的事件监听器
|
||
btn2.addActionListener(this); //c 为按钮添加事件监听器
|
||
this.setTitle("Action Event"); // 设置窗口标题为"Action Event"
|
||
setSize(200,150); // 设置窗口大小为200x150像素
|
||
this.setLayout(new FlowLayout(FlowLayout.CENTER)); //d 设置布局为居中对齐的流式布局
|
||
this.ctpn.add(btn1); // 将"Blue"按钮添加到容器中
|
||
ctpn.add(btn2); // 将"Red"按钮添加到容器中
|
||
this.setVisible(true); // 设置窗口可见
|
||
}
|
||
|
||
public void actionPerformed(ActionEvent e){
|
||
JButton btn=(JButton)e.getSource(); //e 获取触发事件的按钮对象
|
||
if(btn==btn1) ctpn.setBackground(Color.blue); // 如果是"Blue"按钮触发的事件,将容器背景设置为蓝色
|
||
if(btn==btn2) ctpn.setBackground(Color.red); // 如果是"Red"按钮触发的事件,将容器背景设置为红色
|
||
}
|
||
|
||
public static void main(String args[]){
|
||
EventTest frm=new EventTest(); // 创建EventTest对象
|
||
}
|
||
}
|
||
|
||
(2) 程序的运行效果:
|
||
|
||
程序创建了一个窗口,窗口标题为"Action Event",大小为200x150像素。窗口中有两个按钮,一个是"Blue"按钮,另一个是"Red"按钮。当点击"Blue"按钮时,窗口的背景颜色会变为蓝色;当点击"Red"按钮时,窗口的背景颜色会变为红色。
|
||
|
||
程序完成的功能是:该程序演示了如何使用Java的事件处理机制,通过按钮的事件监听器,实现了当点击不同的按钮时,改变窗口的背景颜色。
|
||
|
||
|
||
|
||
|
||
|
||
5.下列代码完成了邮箱系统的登陆功能,请在注释位置编写相应代码,写出运行结果。相关信息和Java帮助如下:
|
||
User表:id username password
|
||
1 zhangsan 123
|
||
2 lisi 234
|
||
数据库操作类已实现,大纲视图如下:
|
||
JDBCUtils
|
||
url:String
|
||
user:String
|
||
password:String
|
||
driver:String
|
||
{...}
|
||
getConnection():Connection
|
||
close(Statement,Connection):void
|
||
close(ResultSet,Statement,Connection):void
|
||
接口Connection下的方法:
|
||
Statement createStatement() 创建一个Statement对象来将SQL语句发送到数据库
|
||
接口Statement下的方法:
|
||
ResultSet executeQuery(String sql) 执行给定的SQL语句,该语句返回单个ResultSet对象。
|
||
接口ResultSet下的方法:
|
||
boolean next() 将光标从当前位置先前移一行。
|
||
|
||
|
||
|
||
import java.sql.*;
|
||
public class LoginTest{
|
||
public static void main(String[] args){
|
||
String username="lisi";
|
||
String pasasword="123";
|
||
boolean flag=new LoginTest().login(username,password);
|
||
if(flag) System.out.println("登陆成功");
|
||
else System.out.println("用户名或密码错误");
|
||
}
|
||
public boolean login(String username,String password){
|
||
if(username==null||password==null){
|
||
return false;
|
||
}
|
||
Connection conn=null;PreparedStatement pstmt=null;ResultSet rs=null;
|
||
try{
|
||
conn=JDBCUtils.getConnection();
|
||
//添加数据库操作代码
|
||
}catch(SQLException e){
|
||
e.printStackTrace();
|
||
}finally{
|
||
JDBCUtils.close(rs,pstmt,conn);
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
answer:
|
||
|
||
|
||
|
||
pstmt = conn.prepareStatement("SELECT * FROM User WHERE username = ? AND password = ?");
|
||
pstmt.setString(1, username);
|
||
pstmt.setString(2, password);
|
||
rs = pstmt.executeQuery();
|
||
if(rs.next()){
|
||
return true; // 用户名和密码匹配,登录成功
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
import java.sql.*;
|
||
|
||
public class LoginTest{
|
||
public static void main(String[] args){
|
||
String username="lisi";
|
||
String password="123";
|
||
boolean flag=new LoginTest().login(username,password);
|
||
if(flag) System.out.println("登陆成功");
|
||
else System.out.println("用户名或密码错误");
|
||
}
|
||
public boolean login(String username,String password){
|
||
if(username==null||password==null){
|
||
return false;
|
||
}
|
||
Connection conn=null;PreparedStatement pstmt=null;ResultSet rs=null;
|
||
try{
|
||
conn=JDBCUtils.getConnection();
|
||
pstmt = conn.prepareStatement("SELECT * FROM User WHERE username = ? AND password = ?");
|
||
pstmt.setString(1, username);
|
||
pstmt.setString(2, password);
|
||
rs = pstmt.executeQuery();
|
||
if(rs.next()){
|
||
return true;
|
||
}
|
||
}catch(SQLException e){
|
||
e.printStackTrace();
|
||
}finally{
|
||
JDBCUtils.close(rs,pstmt,conn);
|
||
}
|
||
return false;
|
||
}
|
||
}
|
||
|
||
运行结果:
|
||
用户名或密码错误
|
||
|
||
程序通过调用login方法进行登录验证,传入用户名和密码参数。在login方法中,首先判断用户名和密码是否为空,如果为空则直接返回false。然后获取数据库连接,通过PreparedStatement对象执行SQL语句查询用户表,使用占位符设置用户名和密码参数。如果查询结果存在,则返回true表示登录成功,否则返回false表示用户名或密码错误。
|
||
|
||
在main方法中,调用login方法并根据返回结果输出相应的提示信息。在本例中,用户名为"lisi",密码为"123",所以输出结果为"用户名或密码错误"。
|
||
|
||
|
||
|
||
|
||
|
||
6.下面有两个Java源文件(Lute.java和Music.java),阅读程序,回答问题。
|
||
a:Lute.java
|
||
package mypack;
|
||
interface Instrument{//乐器
|
||
int NUM=5;
|
||
void play();
|
||
String what();
|
||
void adjust();
|
||
}
|
||
|
||
class Wind implements Instrument{//管乐器
|
||
public void play(){
|
||
System.out.println("Wind.play()");
|
||
}
|
||
public String what() {return "Wind";}
|
||
public void adjust() {}
|
||
}
|
||
class Stringed{//有弦乐器
|
||
int StringNum;
|
||
Stringed(int num){
|
||
this.StringNum=num;
|
||
}
|
||
}
|
||
|
||
public class Lute extends Stringed implements Instruments{//古琵琶
|
||
public Lute(int num){
|
||
super(num);
|
||
}
|
||
public void play(){
|
||
System.out.println("lute.play()");
|
||
}
|
||
public String what() {return "lute"};
|
||
public void adjust() {}
|
||
}
|
||
b.Music.java
|
||
import mypack.*
|
||
public class Music{
|
||
public static void main(String[] args){
|
||
Lute test=new Lute(6);
|
||
test.play();
|
||
}
|
||
}
|
||
|
||
(1)以上代码分别有哪些接口、类,在哪些包中,有公共类吗?
|
||
(2)类Wind中的adjust()方法是抽象方法吗?能省略吗?为什么?
|
||
(3)类Lute和类Stringed是什么关系?Lute类中有成员变量吗?
|
||
(4)类Lute中的方法是public修饰符能省略吗?为什么?
|
||
(5)请写出程序的运行结果。
|
||
|
||
(1)以上代码接口有"Instrument",类有'Wind','Stringed','Lute','Music',都在'mypack'包中。
|
||
在'Lute.java'中有一个公共类'Lute'。在'Music.java'文件中有一个公共类'Music'。
|
||
(2)类Wind中的adjust()方法不是抽象方法。它不能省略。如果省略adjust()方法的实现,则Wind类必须声明为抽象类。
|
||
(3)类Lute是类Stringed的子类。它们之间是继承关系。Lute类中有一个名为StringNum的成员变量。
|
||
(4) 类Lute中的方法的修饰符是public,可以省略。这是因为Lute类实现了Instrument接口,在接口中的所有方法都是公共的,因此在实现接口方法时,默认的访问修饰符是public。
|
||
(5) 程序的运行结果是:lute.play()
|
||
|
||
二.程序设计题
|
||
|
||
1.“具有报警功能的移门”,针对上述描述,请用类、接口等面向对象知识进行设计实现,方法中,不必写出具体实现代码,用System.out.println()。
|
||
|
||
根据描述,我们可以设计以下类和接口来实现具有报警功能的移门:
|
||
|
||
1. 接口:Alarm
|
||
- 方法:void alarm(),用于触发报警功能。
|
||
|
||
2. 类:Door
|
||
- 属性:isOpen(表示门的状态,true表示门开着,false表示门关着)
|
||
- 方法:void open(),用于打开门
|
||
- 方法:void close(),用于关闭门
|
||
- 方法:void alarm(),实现Alarm接口中的方法,用于触发报警功能
|
||
- 方法:void move(),用于移动门的位置
|
||
- 方法:void displayStatus(),用于显示门的当前状态
|
||
|
||
设计实现如下:
|
||
|
||
interface Alarm {
|
||
void alarm();
|
||
}
|
||
|
||
class Door implements Alarm {
|
||
private boolean isOpen;
|
||
|
||
public void open() {
|
||
isOpen = true;
|
||
System.out.println("门已打开");
|
||
}
|
||
|
||
public void close() {
|
||
isOpen = false;
|
||
System.out.println("门已关闭");
|
||
}
|
||
|
||
public void alarm() {
|
||
System.out.println("门正在报警");
|
||
}
|
||
|
||
public void move() {
|
||
System.out.println("门正在移动");
|
||
}
|
||
|
||
public void displayStatus() {
|
||
System.out.println("门的状态:" + (isOpen ? "开着" : "关着"));
|
||
}
|
||
}
|
||
这样设计的类和接口可以实现具有报警功能的移门。Door类实现了Alarm接口,并实现了alarm()方法,用于触发报警功能。同时,Door类还具有打开门、关闭门、移动门、显示门状态的功能。
|
||
|
||
2.数据可视化在统计报表有重要应用,柱状图以及折线图等图形是以不同视角展示数据。假设对于同一份二维数据,系统要求根据不同情景,展示不同图形(柱形图或折线图),且数据变化,图形自动变化(刷新),而且,需要预留接口,以方便需求升级,如同一份数据还支持饼图。为了满足以上需求,请设计类系,并写一个测试类,进行模拟。具体要求:
|
||
(a) 设计一个数据类,且有一份订阅者列表,可具备对订阅者(图形)列表的管理功能(删除与增加),当数据变化时,自动触发订阅者更新图形。
|
||
(b) 设计一个图形的抽象类,具备根据数据绘制图形的功能,并具备订阅数据和取消订阅的功能。
|
||
(c) 写一个测试类,模拟上述过程。
|
||
备注:方法中,不必写出具体实现代码,用System.out.println()说明即可。
|
||
|
||
|
||
|
||
根据需求,我们可以设计以下类来满足要求:
|
||
|
||
1. 数据类:Data
|
||
- 属性:subscribers(订阅者列表)
|
||
- 方法:addSubscriber(Subscriber subscriber),用于添加订阅者
|
||
- 方法:removeSubscriber(Subscriber subscriber),用于移除订阅者
|
||
- 方法:updateData(),用于更新数据并通知订阅者
|
||
|
||
2. 抽象类:Graph
|
||
- 属性:data(数据对象)
|
||
- 方法:subscribe(),用于订阅数据
|
||
- 方法:unsubscribe(),用于取消订阅数据
|
||
- 抽象方法:draw(),用于根据数据绘制图形
|
||
|
||
3. 具体图形类:BarGraph(柱状图)和LineGraph(折线图)
|
||
- 方法:draw(),实现Graph抽象类中的draw()方法,根据数据绘制柱状图或折线图
|
||
|
||
设计实现如下:
|
||
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
// 数据类
|
||
class Data {
|
||
private List subscribers;
|
||
|
||
public Data() {
|
||
subscribers = new ArrayList<>();
|
||
}
|
||
|
||
public void addSubscriber(Graph subscriber) {
|
||
subscribers.add(subscriber);
|
||
}
|
||
|
||
public void removeSubscriber(Graph subscriber) {
|
||
subscribers.remove(subscriber);
|
||
}
|
||
|
||
public void updateData() {
|
||
// 更新数据
|
||
System.out.println("数据更新");
|
||
|
||
// 通知订阅者更新图形
|
||
for (Graph subscriber : subscribers) {
|
||
subscriber.draw();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 抽象图形类
|
||
abstract class Graph {
|
||
protected Data data;
|
||
|
||
public Graph(Data data) {
|
||
this.data = data;
|
||
}
|
||
|
||
public void subscribe() {
|
||
data.addSubscriber(this);
|
||
}
|
||
|
||
public void unsubscribe() {
|
||
data.removeSubscriber(this);
|
||
}
|
||
|
||
public abstract void draw();
|
||
}
|
||
|
||
// 具体图形类:柱状图
|
||
class BarGraph extends Graph {
|
||
public BarGraph(Data data) {
|
||
super(data);
|
||
}
|
||
|
||
public void draw() {
|
||
System.out.println("绘制柱状图");
|
||
}
|
||
}
|
||
|
||
// 具体图形类:折线图
|
||
class LineGraph extends Graph {
|
||
public LineGraph(Data data) {
|
||
super(data);
|
||
}
|
||
|
||
public void draw() {
|
||
System.out.println("绘制折线图");
|
||
}
|
||
}
|
||
|
||
// 测试类
|
||
public class Test {
|
||
public static void main(String[] args) {
|
||
// 创建数据对象
|
||
Data data = new Data();
|
||
|
||
// 创建柱状图和折线图
|
||
Graph barGraph = new BarGraph(data);
|
||
Graph lineGraph = new LineGraph(data);
|
||
|
||
// 订阅数据
|
||
barGraph.subscribe();
|
||
lineGraph.subscribe();
|
||
|
||
// 更新数据,图形自动变化
|
||
data.updateData();
|
||
|
||
// 取消订阅折线图
|
||
lineGraph.unsubscribe();
|
||
|
||
// 更新数据,只有柱状图会变化
|
||
data.updateData();
|
||
}
|
||
}
|
||
根据需求设计了数据类(Data)、抽象图形类(Graph)以及具体图形类(BarGraph和LineGraph)。测试类(Test)中模拟了订阅数据、更新数据以及取消订阅的过程。
|
||
|
||
测试类中先创建了数据对象(Data),然后创建了柱状图(BarGraph)和折线图(LineGraph)。接着订阅了数据,然后更新数据,可以看到柱状图和折线图都会自动绘制图
|
||
形。最后取消了对折线图的订阅,再次更新数据时,只有柱状图会变化。
|
||
|
||
3.当前,在我国,不同的企业类型有不同的税收计算方法,假设有高新企业、外资企业、普通企业。现有税收系统,可计算每一类企业的收税,也可自动计算某个地区(如鄞州区)的税收,一般地,某个地区的企业都有不同类型的企业存在。为了满足以上需求,请设计类系,并写一个测试类,进行模拟。具体要求:
|
||
(a) 设计一抽象类:企业,具备计算税收的功能。
|
||
(b) 高新企业、外资企业、普通企业应该是企业的子类,都具有计算税收的功能。
|
||
(c) 设计一个地区类,它是由不同类型的企业构成,具备计算地区税收的功能。
|
||
(d) 写一个测试类,进行模拟。
|
||
备注:方法中,不必写出具体实现代码,用System.out.println(),或者直接返回一个值进行说明即可。提示:抽象类、方法重写、泛型等的应用。
|
||
|
||
根据需求,我们可以设计以下类来满足要求:
|
||
|
||
1. 抽象类:Enterprise(企业)
|
||
- 方法:calculateTax(),用于计算税收
|
||
|
||
2. 子类:HighTechEnterprise(高新企业)、ForeignEnterprise(外资企业)、NormalEnterprise(普通企业)
|
||
- 方法:calculateTax(),重写父类的计算税收方法
|
||
|
||
3. 类:Region(地区)
|
||
- 属性:enterprises(不同类型的企业列表)
|
||
- 方法:addEnterprise(Enterprise enterprise),用于添加企业
|
||
- 方法:removeEnterprise(Enterprise enterprise),用于移除企业
|
||
- 方法:calculateRegionTax(),用于计算地区税收
|
||
|
||
设计实现如下:
|
||
|
||
|
||
abstract class Enterprise {
|
||
public abstract double calculateTax();
|
||
}
|
||
|
||
class HighTechEnterprise extends Enterprise {
|
||
public double calculateTax() {
|
||
System.out.println("计算高新企业的税收");
|
||
return 0.0;
|
||
}
|
||
}
|
||
|
||
class ForeignEnterprise extends Enterprise {
|
||
public double calculateTax() {
|
||
System.out.println("计算外资企业的税收");
|
||
return 0.0;
|
||
}
|
||
}
|
||
|
||
class NormalEnterprise extends Enterprise {
|
||
public double calculateTax() {
|
||
System.out.println("计算普通企业的税收");
|
||
return 0.0;
|
||
}
|
||
}
|
||
|
||
class Region {
|
||
private List enterprises;
|
||
|
||
public Region() {
|
||
enterprises = new ArrayList<>();
|
||
}
|
||
|
||
public void addEnterprise(Enterprise enterprise) {
|
||
enterprises.add(enterprise);
|
||
}
|
||
|
||
public void removeEnterprise(Enterprise enterprise) {
|
||
enterprises.remove(enterprise);
|
||
}
|
||
|
||
public double calculateRegionTax() {
|
||
double regionTax = 0.0;
|
||
for (Enterprise enterprise : enterprises) {
|
||
regionTax += enterprise.calculateTax();
|
||
}
|
||
return regionTax;
|
||
}
|
||
}
|
||
|
||
public class Test {
|
||
public static void main(String[] args) {
|
||
// 创建地区对象
|
||
Region region = new Region();
|
||
|
||
// 添加不同类型的企业
|
||
region.addEnterprise(new HighTechEnterprise());
|
||
region.addEnterprise(new ForeignEnterprise());
|
||
region.addEnterprise(new NormalEnterprise());
|
||
|
||
// 计算地区税收
|
||
double regionTax = region.calculateRegionTax();
|
||
System.out.println("地区税收:" + regionTax);
|
||
}
|
||
}
|
||
根据需求设计了抽象类Enterprise、子类HighTechEnterprise、ForeignEnterprise和NormalEnterprise,以及类Region。测试类(Test)中模拟了创建地区对象、添加不同类型的企业、计算地区税收的过程。
|
||
|
||
测试类中先创建了地区对象(Region),然后添加了高新企业(HighTechEnterprise)、外资企业(ForeignEnterprise)和普通企业(NormalEnterprise)。接着计算地区税收,可以看到会调用各个企业子类的计算税收方法,并计算出地区的总税收。最后将地区税收输出。
|
||
|