首先需要明确的是,对象的构造和初始化是面向对象编程中非常重要的概念,它影响着对象的生命周期和对象各个属性的默认值。
什么是构造函数
在Java中,每个类都有一个构造函数,它是一个特殊的方法,用于实例化对象时被调用,构造函数通常用于初始化对象的属性,并确保对象在被实例化后能够正常使用。
在Java中,构造函数的名字与类名相同,没有返回值,可以像方法一样拥有参数列表。例如:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
在这个例子中,Person类有一个构造函数,它有两个参数:name和age。构造函数用于初始化类的属性值,this关键字用于引用对象本身,可以在构造函数中使用它来访问类的成员变量。
构造函数的调用
当创建一个对象时,Java VM会自动为该对象分配内存,并调用类的构造函数初始化该对象的各个属性。例如:
Person p1 = new Person("张三", 21);
在这个例子中,我们创建了一个Person类的对象p1,并通过构造函数将name属性设置为"张三",并将age属性设置为21。
与方法不同,构造函数不可以被直接调用,而只能通过创建对象的方式来调用。
默认构造函数
默认构造函数是指没有参数的构造函数,如果一个类没有使用任何构造函数,Java编译器会自动生成一个默认构造函数,这个构造函数的行为与没有参数的构造函数类似,它会将对象的属性设置为默认值。
例如,当使用下面的代码创建一个Person对象时:
Person p2 = new Person();
由于Person类没有显式定义任何构造函数,Java编译器会自动为Person类生成一个默认构造函数,此时p2的属性值都是默认值。
构造函数的重载
Java中允许有多个构造函数,只要它们的参数列表不同,就可以实现构造函数的重载。例如,我们可以为Person类提供另一个具有单个参数的构造函数来初始化name属性:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name) {
this.name = name;
this.age = 0;
}
}
在这个例子中,Person类提供了两个构造函数,分别具有不同的参数列表。我们可以使用下面的代码调用其中的一个构造函数:
Person p3 = new Person("李四", 18);
Person p4 = new Person("王五");
在这个例子中,我们分别创建了两个Person对象:p3和p4。p3使用了有两个参数的构造函数,而p4使用了仅有一个参数的构造函数。
对象初始化块
除了构造函数外,Java还允许在类中使用初始化块来初始化类的静态或实例变量。初始化块会在对象被创建时执行,并按照定义的顺序依次执行。
一个类可以拥有多个初始化块,可以在一个初始化块中进行复杂的初始化操作,例如使用循环和条件语句对变量进行赋值。
下面是一个拥有多个实例初始化块的例子:
public class Test {
private int x;
private int y;
{
System.out.println("第一个实例初始化块运行");
x = 10;
}
{
System.out.println("第二个实例初始化块运行");
y = 20;
}
public Test() {
System.out.println("构造函数运行");
}
public static void main(String[] args) {
Test t = new Test();
}
}
在这个例子中,我们定义了两个实例初始化块来初始化x和y变量。运行这个程序会得到以下输出:
第一个实例初始化块运行
第二个实例初始化块运行
构造函数运行
注意,在创建对象的过程中,x和y的初始化顺序是先执行第一个初始化块,然后执行第二个初始化块,最后执行构造函数。
示例说明
示例一
我们有一个圆形类:
public class Circle {
private double radius; //半径
private double area; //面积
public Circle(double radius) { //构造函数,初始化半径
this.radius = radius;
this.area = Math.PI * radius * radius;
}
public void setRadius(double radius) { //设置圆的半径,并重新计算面积
this.radius = radius;
this.area = Math.PI * radius * radius;
}
public double getRadius() {
return radius;
}
public double getArea() {
return area;
}
}
在这个例子中,我们定义了一个Circle类,它有一个构造函数,用于初始化半径,并计算圆的面积。注意,这里使用了Math类中的PI常量来计算圆面积。
现在,我们可以使用以下代码来创建若干个Circle对象:
Circle c1 = new Circle(1.0);
Circle c2 = new Circle(2.0);
Circle c3 = new Circle(3.0);
System.out.println("c1: " + c1.getRadius() + ", " + c1.getArea()); //输出:c1: 1.0, 3.141592653589793
System.out.println("c2: " + c2.getRadius() + ", " + c2.getArea()); //输出:c2: 2.0, 12.566370614359172
System.out.println("c3: " + c3.getRadius() + ", " + c3.getArea()); //输出:c3: 3.0, 28.274333882308138
在这个例子中,我们分别创建了三个Circle对象:c1、c2和c3,它们的半径分别为1、2和3,面积分别为3.1415、12.5663和28.2743。
示例二
我们有一个学生类:
public class Student {
private static int count = 0; //统计学生人数
private String name; //学生姓名
private int age; //年龄
private String major; //专业
{
count++; //每次创建对象时,学生人数增加1
}
public Student(String name, int age, String major) { //构造函数,初始化姓名、年龄和专业
this.name = name;
this.age = age;
this.major = major;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getMajor() {
return major;
}
public static int getCount() { //获取学生人数
return count;
}
}
在这个例子中,我们定义了一个Student类,它有一个构造函数,用于初始化姓名、年龄和专业。此外,我们使用了一个实例初始化块来统计学生人数。
现在,我们可以使用以下代码来创建若干个Student对象:
Student s1 = new Student("张三", 18, "计算机科学");
Student s2 = new Student("李四", 20, "电子工程");
Student s3 = new Student("王五", 21, "机械制造");
System.out.println("学生总人数:" + Student.getCount()); //输出:学生总人数:3
在这个例子中,我们分别创建了三个Student对象:s1、s2和s3,每次创建对象时,学生人数都会增加1。
最后,我们使用静态方法getCount()来获取学生总人数,并输出在控制台上。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 超详细讲解对象的构造及初始化 - Python技术站