讲师中心 微信公众号
AI工具推荐 视频效率加速

Java 中如何正确调用子类的交互式菜单方法(含完整可运行示例)

胖杰同学_2451

胖杰同学_2451

发布时间:2026-02-12 09:24:56

|

788人浏览过

|

来源于php中文网

原创

Java 中如何正确调用子类的交互式菜单方法(含完整可运行示例)

本文详解如何在 java 主类中成功调用另一个类(如 bankaccount)中的交互式菜单方法,重点解决因缺少输入读取导致菜单“一闪而过”的常见问题,并提供结构清晰、健壮可用的银行账户模拟代码。

在 Java 面向对象编程实践中,将业务逻辑(如银行账户操作)封装到独立类中,再由 main 类负责初始化与驱动,是一种标准且推荐的设计方式。但初学者常遇到一个典型问题:菜单方法(如 menu())看似被调用了,控制台却只显示欢迎信息和选项列表,随后程序立即退出——根本原因在于菜单逻辑未进入持续交互循环,且关键的用户输入未被读取与处理。

下面是一段修复后的完整可运行代码,已补充缺失的输入处理、菜单循环、功能分支及边界保护:

import java.util.Scanner;

public class BankApplication {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter your 'Name' and 'CustomerId' to access your Bank account:");
        String name = sc.nextLine().trim();
        String customerId = sc.nextLine().trim();

        // 防止空用户名或ID导致异常
        if (name.isEmpty() || customerId.isEmpty()) {
            System.out.println("Error: Name and Customer ID cannot be empty.");
            return;
        }

        BankAccount obj1 = new BankAccount(name, customerId);
        obj1.menu(); // ✅ 正确触发菜单逻辑
        sc.close(); // 释放资源
    }
}

class BankAccount {
    private double bal = 0.0;           // 初始余额为0
    private double prevTrans = 0.0;     // 上次交易金额(正为存,负为取)
    private final String customerName;
    private final String customerId;

    public BankAccount(String customerName, String customerId) {
        this.customerName = customerName;
        this.customerId = customerId;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            bal += amount;
            prevTrans = amount;
            System.out.println("✓ Deposited: $" + amount);
        } else {
            System.out.println("⚠ Invalid deposit amount.");
        }
    }

    public void withdraw(double amount) {
        if (amount <= 0) {
            System.out.println("⚠ Invalid withdrawal amount.");
        } else if (amount > bal) {
            System.out.println("❌ Insufficient balance. Current balance: $" + bal);
        } else {
            bal -= amount;
            prevTrans = -amount;
            System.out.println("✓ Withdrawn: $" + amount);
        }
    }

    public void getPreviousTrans() {
        if (prevTrans > 0) {
            System.out.println("→ Last transaction: Deposited $" + prevTrans);
        } else if (prevTrans < 0) {
            System.out.println("→ Last transaction: Withdrawn $" + Math.abs(prevTrans));
        } else {
            System.out.println("→ No transaction yet.");
        }
    }

    public void checkBalance() {
        System.out.println("? Current balance: $" + bal);
    }

    public void menu() {
        Scanner sc = new Scanner(System.in);
        System.out.println("\n" + "=".repeat(40));
        System.out.println("? Welcome, " + customerName + " | ID: " + customerId);
        System.out.println("=".repeat(40));

        char option;
        do {
            System.out.println("\nPlease select an option:");
            System.out.println("a) Check Balance");
            System.out.println("b) Deposit");
            System.out.println("c) Withdraw");
            System.out.println("d) Show Last Transaction");
            System.out.println("e) Exit");
            System.out.print("→ Enter option (a-e): ");

            // ✅ 关键修复:必须读取用户输入,否则菜单无法响应
            String input = sc.nextLine().trim();
            if (input.length() == 0) continue;
            option = input.charAt(0);

            switch (option) {
                case 'a':
                case 'A':
                    checkBalance();
                    break;
                case 'b':
                case 'B':
                    System.out.print("Enter deposit amount: $");
                    try {
                        double amt = Double.parseDouble(sc.nextLine().trim());
                        deposit(amt);
                    } catch (NumberFormatException e) {
                        System.out.println("⚠ Invalid number format.");
                    }
                    break;
                case 'c':
                case 'C':
                    System.out.print("Enter withdrawal amount: $");
                    try {
                        double amt = Double.parseDouble(sc.nextLine().trim());
                        withdraw(amt);
                    } catch (NumberFormatException e) {
                        System.out.println("⚠ Invalid number format.");
                    }
                    break;
                case 'd':
                case 'D':
                    getPreviousTrans();
                    break;
                case 'e':
                case 'E':
                    System.out.println("? Thank you for banking with us. Goodbye!");
                    break;
                default:
                    System.out.println("⚠ Invalid option. Please choose a-e.");
            }
        } while (option != 'e' && option != 'E');

        sc.close(); // 确保菜单内Scanner也关闭(注意:若main中已close,则此处需避免重复关闭;本例中menu独占Scanner更安全)
    }
}

✅ 关键要点总结:

OpenJDK 24
OpenJDK 24

OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。

下载
  • 菜单必须是循环结构:使用 do-while 或 while(true) 持续等待用户选择,而非单次执行后退出;
  • 必须显式读取输入:sc.nextLine()(或 sc.next())不可省略,否则 switch 将无输入可判断;
  • 输入校验必不可少:对空输入、非法字符、非数字金额做防御性处理,提升鲁棒性;
  • 资源管理要规范:每个 Scanner 实例应在使用完毕后 close(),避免资源泄漏;
  • 封装与职责分离:BankAccount 负责状态与行为,BankApplication 仅负责启动与协调,符合单一职责原则。

运行此代码后,你将看到完整的交互式银行菜单,支持反复操作直至主动选择退出。这不仅是语法修正,更是面向对象设计思维的实践落地。

立即学习“Java免费学习笔记(深入)”;

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

1071

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

1417

2024.03.13

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

6515

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

342

2025.11.27

C++ 面向对象编程与设计模式实践
C++ 面向对象编程与设计模式实践

本专题整合了 C++ 面向对象编程的核心机制,涵盖类的定义与访问控制、构造函数与析构函数、拷贝语义与移动语义、继承与虚函数多态、抽象类与接口、运算符重载、友元函数等关键知识点,同时结合单例模式、工厂模式、观察者模式、策略模式等常用设计模式的 C++ 实现,帮助开发者写出结构清晰、易于维护的面向对象代码。

344

2026.04.09

Java 面向对象与核心编程机制
Java 面向对象与核心编程机制

系统讲解 Java 面向对象编程的核心知识体系,涵盖类的定义与封装、构造方法与 this/super 关键字、继承与方法重写、多态与向上向下转型、抽象类与接口的区别与设计原则、异常处理机制(try-catch-finally / 自定义异常)、泛型的类型参数与通配符、集合框架(List/Set/Map)的使用与遍历方式,帮助开发者全面掌握 Java 程序设计的核心机制与面向对象思维。

223

2026.04.17

OpenJDK JVM参数怎么调优
OpenJDK JVM参数怎么调优

Java应用运行缓慢,如何调整JVM参数?本专题介绍OpenJDK JVM性能调优的基本流程,涵盖性能指标确认、运行数据采集、内存配置和垃圾回收分析,帮助你先定位瓶颈,再通过对照测试验证效果,避免直接套用参数而影响应用稳定性。

80

2026.10.16

OpenJDK怎么配置Java开发环境
OpenJDK怎么配置Java开发环境

怎样用OpenJDK搭建开发环境?本专题介绍版本选择、下载安装、环境变量配置和编译运行验证,帮助你理清JDK的作用及基本配置流程,并通过简单程序检查环境是否可用,为后续项目开发做好准备。

40

2026.10.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn