jmu-Java-PTA题解 ( jmu-Java-03面向对象基础-02-构造方法与初始化块) 网安2312陈卓

问题要求

1.定义一个Person类

属性:String name, boolean gender, int age, int id ,所有的变量必须为私有(private)。
无参构造函数:Person(), 功能:打印This is constructor 。
有参构造函数:Person(name, gender, age),功能:给属性赋值。
建议:使用Eclipse自动生成toString方法

2.定义类的初始化块

为Person类加入初始化块,在初始化块中对id属性赋值,并且要保证每次的值比上次创建的对象的值+1。然后在下一行打印This is initialization block, id is ... 其中...是id的值。
提示:可为Person类定义一个static属性来记录所创建的对象个数。

3.编写静态初始化块

打印This is static initialization block

4.编写main方法

  • 首先输入n,代表要创建的对象数量。
  • 然后从控制台分别读取n行的name age gender, 并调用有参构造函数Person(name, age, gender)新建对象 。
  • 将创建好的n个对象逆序输出(即输出toString()方法)。
  • 使用无参构造函数新建一个Person对象,然后直接打印该对象。

思考

初始化类与对象有几种方法,构造函数、初始化块、静态初始化块。这三种方法执行的先后顺序是什么?各执行几次。

输入样例:

3
a 11 false
b 12 true
c 10 false

输出样例:

This is static initialization block
This is initialization block, id is 0
This is initialization block, id is 1
This is initialization block, id is 2
Person [name=c, age=10, gender=false, id=2]
Person [name=b, age=12, gender=true, id=1]
Person [name=a, age=11, gender=false, id=0]
This is initialization block, id is 3
This is constructor
null,0,false,3
Person [name=null, age=0, gender=false, id=3]

关键点

  • 类的设计:确保Person类的属性私有化,并正确实现构造函数、初始化块和静态初始化块。
  • 对象初始化逻辑:保证id属性在初始化块中的赋值逻辑正确,构造函数能正确赋值其他属性。
  • 输入输出处理:在main方法中准确读取输入并按要求输出对象信息。
  • 初始化顺序理解:明确构造函数、初始化块、静态初始化块的执行顺序和执行次数。

解题步骤

第一步:设计Person类

私有属性保证数据封装,count用于记录对象个数,静态初始化块在类加载时执行,打印相关信息,实例初始化块在每次创建对象时执行,对id赋值并打印信息,构造函数分别实现无参和有参的对象初始化操作,toString方法提供对象的字符串表示。

class Person {
    // 私有属性
    private String name;
    private boolean gender;
    private int age;
    private int id;
    // 静态属性,用于记录创建对象的个数
    private static int count = 0;

    // 静态初始化块
    static {
        System.out.println("This is static initialization block");
    }

    // 实例初始化块
    {
        id = count++;
        System.out.println("This is initialization block, id is " + id);
    }

    // 无参构造函数
    public Person() {
        System.out.println("This is constructor");
        System.out.println(name + "," + age + "," + gender + "," + id);
    }

    // 有参构造函数
    public Person(String name, boolean gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
        // 注意这里不需要再处理id,id在实例初始化块中已处理
    }

    // 重写toString方法,使用Eclipse自动生成
    @Override
    public String toString() {
        return "Person [" +
                "name=" + name +
                ", age=" + age +
                ", gender=" + gender +
                ", id=" + id +
                ']';
    }
}

第二步:编写Main类进行输入处理和输出

读取输入的对象数量n,循环读取name age gender,调用有参构造函数创建对象,逆序遍历对象数组,输出对象信息,使用无参构造函数创建对象并输出。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Person[] person = new Person[n];

        // 读取输入并创建对象
        for (int i = 0; i < n; i++) {
            String name = in.next();
            int age = in.nextInt();
            boolean gender = in.nextBoolean();
            person[i] = new Person(name, gender, age);
        }

        // 逆序输出对象
        for (int i = n - 1; i >= 0; i--) {
            System.out.println(person[i]);
        }

        // 使用无参构造函数创建并输出对象
        Person personDefault = new Person();
        System.out.println(personDefault);

        in.close();
    }
}

整体流程图:

整体代码:

import java.util.Scanner;
class Person{
    private String name;
    private boolean gender;
    private int age;
    private static int count = 0;
    private int id = count;

    public void Person(){
        System.out.println("This is constructor");
        System.out.println(name+","+age+","+gender+","+id);
    }
    
    public Person(){
        System.out.println("This is initialization block, id is "+count);
    }

    static{
        System.out.println("This is static initialization block");
    }

    public String toString() {
        return "Person [" +
                "name=" + name +
                ", age=" + age +
                ", gender=" + gender +
                ", id=" + id +
                ']';
    }

    public void Person(String name, boolean gender, int age){
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.count++;
    }

}
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        Person[] person = new Person[n];
        for (int i = 0; i < n; i++) {
            String name = in.next();
            int age = in.nextInt();
            boolean gender = in.nextBoolean();
            person[i] = new Person();
            person[i].Person(name, gender, age);
        }
        for (int i = n - 1; i >= 0; i--) {
            System.out.println(person[i]);
        }
        Person persons = new Person();
        persons.Person();
        System.out.println(persons);
    }
}

思考:在 Java 中,初始化类与对象主要有构造函数、初始化块、静态初始化块这三种方法,它们在执行顺序和执行次数上都有着明确的规则和特点。从执行顺序来看,静态初始化块优先执行。当 Java 虚拟机加载类时,会首先执行静态初始化块,这是因为静态初始化块主要用于初始化类的静态成员,例如静态变量、静态常量等,为类的后续使用做准备,且仅执行一次。例如在我们定义的Person类中,“This is static initialization block” 会最先被输出。接着执行的是实例初始化块。当使用new关键字创建对象时,实例初始化块在构造函数之前执行。实例初始化块用于对对象的非静态属性进行通用的初始化操作,比如在Person类中,通过实例初始化块给id属性赋值,并打印相关信息。最后执行构造函数。构造函数用于对对象进行个性化的初始化,根据传入的参数为对象的属性赋值。比如Person类的有参构造函数会根据传入的name、gender、age为对象赋值;无参构造函数则会输出对象的相关信息,包括默认值。从执行次数上看,静态初始化块只在类加载时执行一次。实例初始化块和构造函数则是每次创建对象时都会执行。例如在main方法中创建多个Person对象,实例初始化块和构造函数会随着对象的创建而执行相应次数。深入理解这三种初始化方法的执行顺序和执行次数,对于编写健壮、高效的 Java 代码至关重要,能确保对象在创建过程中属性的正确初始化,满足程序的业务逻辑需求。

posted @ 2025-05-12 16:35  取名字比写博客还难  阅读(33)  评论(0)    收藏  举报