首页 > Java > java教程 > 正文

解决Java do-while 循环、switch 语句与继承中的常见错误

DDD
发布: 2025-09-26 08:10:38
原创
243人浏览过

解决Java do-while 循环、switch 语句与继承中的常见错误

本教程旨在解决Java编程中在使用do-while循环与switch语句时常见的变量作用域问题,以及在继承体系中子类构造器调用父类构造器时易犯的错误。文章将通过具体代码示例,详细阐述如何正确处理变量声明、super()关键字的使用,并优化程序的用户交互逻辑,确保代码的健壮性和可读性。

java开发中,初学者常会在控制流结构(如do-while循环和switch语句)以及面向对象特性(如继承和构造器)的使用上遇到挑战。本文将深入探讨两个常见的错误场景:变量作用域问题导致的cannot find symbol错误,以及继承中子类构造器调用父类构造器不当导致的constructor cannot be applied错误,并提供详细的解决方案和优化建议。

1. 理解变量作用域与do-while循环

在使用do-while循环时,一个常见的错误是将循环控制变量声明在do块内部。由于Java的作用域规则,在代码块({})内部声明的变量,其生命周期和可见性仅限于该代码块。这意味着,如果choice变量在do块内部声明,那么while条件语句就无法访问它,从而导致cannot find symbol编译错误

错误示例分析:

do {
    // ...
    Scanner input = new Scanner(System.in);
    int choice = input.nextInt(); // choice 在 do 块内部声明
    // ...
} while (choice != 0); // 错误:choice 在此处不可见
登录后复制

解决方案: 要解决这个问题,只需将循环控制变量(例如choice)的声明移到do-while循环的外部。这样,choice就拥有了更广的作用域,可以在整个do-while结构中被访问和修改。同时,Scanner对象也应在循环外部创建一次,以避免不必要的资源开销和潜在的资源泄漏。

修正后的代码片段(Main类):

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in); // Scanner 在循环外部声明一次
        int choice; // choice 声明在 do-while 循环外部

        do {
            System.out.println("\nWhat size dog do you want to get!:\n" +
                               "1) small\n" + "2) medium\n" + "3) large\n" + "0) quit\n" +
                               "and any other number for non dog options!");

            choice = input.nextInt(); // 在循环内部读取用户输入

            switch (choice) {
                case 1:
                    // ... 处理小型犬逻辑 ...
                    break;
                case 2:
                    // ... 处理中型犬逻辑 ...
                    break;
                case 3:
                    // ... 处理大型犬逻辑 ...
                    break;
                case 0:
                    // 用户选择退出,无需额外操作,循环条件会处理
                    break;
                default:
                    System.out.println("We are only giving dogs up for adoption today!");
            }
        } while (choice != 0); // choice 在此处可见
        System.out.println("Goodbye\n");
        input.close(); // 关闭 Scanner 资源
    }
}
登录后复制

2. Java继承中构造器的正确使用

在Java的继承体系中,子类构造器在执行前必须先调用其父类的构造器。这是因为子类会继承父类的成员变量,而这些成员变量的初始化通常由父类的构造器负责。如果子类构造器没有显式调用父类构造器,编译器会尝试插入一个默认的无参父类构造器调用(super())。然而,如果父类只定义了带参数的构造器而没有无参构造器,就会导致constructor Animal in class Animal cannot be applied to given types的编译错误。

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

此外,子类不应重复声明父类中已经存在的成员变量。子类通过继承自动拥有父类的公共和受保护成员。如果子类再次声明同名成员,会造成“隐藏”父类成员的现象,这通常不是期望的行为,且会增加代码的复杂性和出错的可能性。

错误示例分析:

Animal 类:

public class Animal {
    private String name;
    private Integer age;
    private String breed;
    private String behavior;

    public Animal(String name, Integer age, String breed, String behavior) {
        this.name = name;
        this.age = age;
        this.breed = breed;
        this.behavior = behavior;
    }
    // ... 其他方法 ...
}
登录后复制

Dog 类(错误):

DeepBrain
DeepBrain

AI视频生成工具,ChatGPT +生成式视频AI =你可以制作伟大的视频!

DeepBrain 94
查看详情 DeepBrain
public class Dog extends Animal{
    // 冗余地重复声明了父类已有的成员变量
    public String name;
    public int age;
    public String breed;
    public String behavior;

    public Dog(String name, Integer age, String breed, String behavior) {
        // 没有调用父类构造器,且试图重新初始化父类已有的成员
        this.name = name;
        this.age = age;
        this.breed = breed;
        this.behavior = behavior;
    }
}
登录后复制

解决方案:

  1. 在子类构造器的第一行,使用super()关键字显式调用父类的构造器,并传入相应的参数来初始化父类的成员。
  2. 移除子类中与父类重复的成员变量声明。子类会自动继承这些成员。

修正后的代码片段(Dog类):

public class Dog extends Animal {
    // 无需在此重复声明 name, age, breed, behavior 等父类已有的成员变量
    // 如果 Dog 类有 Animal 类没有的特有属性,则在此声明。

    public Dog(String name, Integer age, String breed, String behavior) {
        super(name, age, breed, behavior); // 显式调用父类 Animal 的构造器
    }
    // ... Dog 类特有的方法或属性 ...
}
登录后复制

3. 优化用户交互与程序控制流

根据用户需求,“如果用户输入5表示同意领养,则显示再见消息;如果输入6或更高,则循环返回主菜单。”这要求我们对程序的控制流进行更精细的设计。原始的do-while (choice != 0)只处理了0退出,没有考虑到5的退出逻辑。

优化思路:

  1. 主循环的退出条件应包含用户选择“退出”(0)和“领养”(5)两种情况。
  2. 在用户选择具体犬种(case 1, 2, 3)后,再提示用户是否领养,并根据用户的二次输入来更新主循环的控制变量。

修正后的Main类代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int choice; // 主菜单选择
        final int QUIT_OPTION = 0;
        final int ADOPT_OPTION = 5;
        final int NO_ADOPT_OPTION_MIN = 6;

        do {
            System.out.println("\nWhat size dog do you want to get!:\n" +
                               "1) small\n" + "2) medium\n" + "3) large\n" +
                               QUIT_OPTION + ") quit\n" +
                               "and any other number for non dog options!");

            choice = input.nextInt();

            switch (choice) {
                case 1:
                    System.out.println("We have one small breeded dog. A Chihuahua is up for adoption!");
                    System.out.println("\nHere is more information!");
                    Chihuahua goliath = new Chihuahua("Goliath", 4, "Chihuahua", "aggressive");
                    goliath.printDogInfo();
                    System.out.println("\nTo take me home press " + ADOPT_OPTION + ", or " + NO_ADOPT_OPTION_MIN + " or higher for no!");
                    int takeHomeChoice1 = input.nextInt();
                    if (takeHomeChoice1 == ADOPT_OPTION) {
                        choice = ADOPT_OPTION; // 设置 choice 为 5,使主循环终止
                    }
                    // 如果 takeHomeChoice1 >= 6,choice 保持不变,主循环会继续
                    break;

                case 2:
                    System.out.println("We have one medium breeded dog. A Labrador is up for adoption!");
                    System.out.println("\nHere is more information!");
                    Labrador hendrix = new Labrador("Hendrix", 8, "Labrador", "not aggressive");
                    hendrix.printDogInfo();
                    System.out.println("\nTo take me home press " + ADOPT_OPTION + ", or " + NO_ADOPT_OPTION_MIN + " or higher for no!");
                    int takeHomeChoice2 = input.nextInt();
                    if (takeHomeChoice2 == ADOPT_OPTION) {
                        choice = ADOPT_OPTION;
                    }
                    break;

                case 3:
                    System.out.println("We have one large breeded dog. A Great dane is up for adoption!");
                    System.out.println("\nHere is more information!");
                    Greatdane toodles = new Greatdane("Toodles", 2, "Greatdane", "not aggressive");
                    toodles.printDogInfo();
                    System.out.println("\nTo take me home press " + ADOPT_OPTION + ", or " + NO_ADOPT_OPTION_MIN + " or higher for no!");
                    int takeHomeChoice3 = input.nextInt();
                    if (takeHomeChoice3 == ADOPT_OPTION) {
                        choice = ADOPT_OPTION;
                    }
                    break;

                case QUIT_OPTION:
                    // 用户直接选择退出,choice 已经是 0,循环条件会处理
                    break;

                default:
                    System.out.println("We are only giving dogs up for adoption today!");
                    // 其他无效输入,循环继续
            }
        } while (choice != QUIT_OPTION && choice != ADOPT_OPTION); // 循环直到选择退出 (0) 或领养 (5)

        System.out.println("\nGoodbye!"); // 统一的退出消息
        input.close(); // 关闭 Scanner 资源
    }
}
登录后复制

注意事项与总结:

  • 变量作用域: 始终确保变量在需要访问它的代码块中声明,或者声明在更广阔的作用域中。
  • 继承与构造器: 子类构造器必须通过super()显式调用父类构造器来完成父类部分的初始化。避免在子类中重复声明父类已有的成员变量。
  • 程序控制流: 精心设计循环条件和内部逻辑,以准确反映用户的意图和程序的预期行为。对于复杂的交互,可以考虑使用嵌套循环或更复杂的条件判断。
  • 资源管理: 对于像Scanner这样的资源,在使用完毕后务必调用close()方法释放资源,避免资源泄漏。
  • 代码可读性 使用常量(final关键字)代替“魔术数字”(Magic Numbers),如QUIT_OPTION、ADOPT_OPTION,可以显著提高代码的可读性和可维护性。

通过遵循这些原则,您可以编写出更健壮、更易于理解和维护的Java代码。

以上就是解决Java do-while 循环、switch 语句与继承中的常见错误的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号