构造函数与初始化块

简介: 构造函数与初始化块

7-2 jmu-Java-03面向对象基础-02-构造函数与初始化块


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, gender, age, 并调用有参构造函数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]


代码:


package 测试;
import java.util.*;
public class Main {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    try (Scanner cin = new Scanner(System.in)) {
      int n = cin.nextInt();
      Person[] a = new Person[n];
      for (int i = 0; i < n; i++) {
        String name = cin.next();
        int age = cin.nextInt();
        boolean gender = cin.nextBoolean();
        a[i] = new Person(name, age, gender, i);
//        System.out.println(name + " " + age + " " + gender);
      }
      for (int i = n - 1; i >= 0; i--) {
        System.out.println(a[i].toString());
      }
      @SuppressWarnings("unused")
      Person b = new Person(n);
    }
  }
}
class Person {
  private String name;
  private boolean gender;
  private int age;
  private int id;
  static {
    System.out.println("This is static initialization block");
  }
  public Person(int id) {
    System.out.println("This is initialization block, id is " + id);
    System.out.println("This is constructor");
    System.out.println(name + "," + age + "," + gender + "," + id);
    System.out.println("Person " + "[name=" + name + ", age=" + age + ", gender=" + gender + ", id=" + id + "]");
  }
  public Person(String name, int age, boolean gender, int id) {
    super();
    System.out.println("This is initialization block, id is " + id);
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.id = id;
  }
  @Override
  public String toString() {
    return "Person [name=" + name + ", age=" + age  + ", gender=" + gender+ ", id=" + id + "]";
  }
}


思考回答:


继承场景执行顺序:

父类静态初始化块->子类静态初始化块->父类非静态初始化块->父类构造函数->子类非静态初始化块->子类构造函数

非继承场景执行顺序:

静态初始化块->非静态初始化块->构造函数


静态初始化块:类加载时隐式调用

普通初始化块:创建对象时隐式调用


  •  静态初始化块的优先级最高,也就是最先执行,并且只在所有该类实例中的第一个实例初始化时执行;
  •    非静态初始化块和构造函数后执行,并且在每次生成类实例时执行一次;
  •   非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
  •    静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
  •    非静态初始化块可以针对多个重载构造函数进行代码复用。


目录
相关文章
|
7月前
|
C++
C++静态成员变量及函数
C++静态成员变量及函数
46 0
|
3月前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
78 30
|
7月前
|
编译器 C#
C#构造函数详解
C#构造函数详解
63 0
|
7月前
|
编译器
static关键字修饰成员变量与成员函数
1. static概念 声明 为static的类成员称为类的静态成员,用static修饰的成员变量,称为静态成员变量;用static修饰的成员函数,称为静态成员函数,都存放在堆区。 静态成员变量一定要在类外进行初始化。
132 0
|
编译器 C++
C++中虚继承时的构造函数
在虚继承中,虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数。对最终的派生类来说,虚基类是间接基类,而不是直接基类。这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。 下面我们以菱形继承为例来演示构造函数的调用: #include <iostream> using namespace std; //虚基类A class A{ public: A(int a); protected: int m_a; }; A:
112 1
|
编译器
匿名对象与构造器
匿名对象与构造器
76 0
|
Java 编译器
构造函数中为什么要用this关键字?
构造函数中为什么要用this关键字?
82 0
|
编译器 C语言 C++
C嘎嘎~~[构造函数提升篇]
C嘎嘎~~[构造函数提升篇]
Zp
父类静态代码块、非静态代码块、构造方法、子类静态代码块、子类非静态代码块、子类构造方法执行顺序
父类静态代码块、非静态代码块、构造方法、子类静态代码块、子类非静态代码块、子类构造方法执行顺序
Zp
75 0
|
存储 编译器 C语言
【三、类中的静态成员】静态成员变量与静态成员函数(static关键字、this指针)
【三、类中的静态成员】静态成员变量与静态成员函数(static关键字、this指针)
160 0