Java面向对象基础——2.构造方法
Java构造方法
构造方法的基本概念与作用
在Java面向对象编程中,构造方法(Constructor)是创建对象时必须调用的特殊方法,它负责对象的初始化工作。与普通方法相比,构造方法具有以下特点:
- 构造方法的名称必须与类名完全相同
- 构造方法没有返回值,也不能使用
void声明 - 构造方法可以重载(定义多个参数不同的构造方法)
- 构造方法必须通过
new操作符调用
为什么需要构造方法?
在没有构造方法的情况下,创建对象后需要单独调用setter方法初始化字段:
Person person = new Person();
person.setName("张三");
person.setAge(25);
这种方式存在两个问题:一是步骤繁琐,二是可能遗漏某些初始化步骤导致对象状态不正确。构造方法可以解决这些问题,在创建对象的同时完成初始化:
// 使用构造方法创建并初始化对象
Person person = new Person("张三", 25);
构造方法的定义与使用
基本语法
public class 类名 {
// 字段定义
private 类型 字段1;
private 类型 字段2;
// 构造方法
public 类名(参数1, 参数2, ...) {
// 初始化字段
this.字段1 = 参数1;
this.字段2 = 参数2;
// 其他初始化逻辑
}
}
示例:为Person类定义构造方法
public class Person {
private String name;
private int age;
// 构造方法:初始化name和age字段
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
public static void main(String[] args) {
// 使用构造方法创建对象
Person person = new Person("张三", 25);
System.out.println("姓名:" + person.getName()); // 输出"张三"
System.out.println("年龄:" + person.getAge()); // 输出25
}
}
在这个例子中,Person类定义了一个接收name和age参数的构造方法,通过new Person("张三", 25)创建对象时,会自动调用该构造方法完成初始化。
注:虽然构造方法本身不写返回值,但 new 操作会返回对象引用。
默认构造方法
如果一个类没有显式定义任何构造方法,Java编译器会自动生成一个默认构造方法。默认构造方法没有参数,也没有任何执行语句:
public class Person {
private String name;
private int age;
// 编译器自动生成的默认构造方法
public Person() {
// 空方法体
}
}
此时可以通过new Person()创建对象:
Person person = new Person(); // 调用默认构造方法
注意事项
- 一旦显式定义了任何构造方法,编译器将不再生成默认构造方法
- 如果需要同时支持无参数创建对象,必须显式定义无参数构造方法
public class Person {
private String name;
private int age;
// 显式定义有参数构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 显式定义无参数构造方法
public Person() {
// 可以在这里设置默认值
this.name = "未知姓名";
this.age = 0;
}
}
构造方法的重载
与普通方法一样,构造方法也支持重载(Overload),即一个类可以定义多个构造方法,只要它们的参数列表(参数数量、类型或顺序)不同。
示例:重载构造方法
public class Person {
private String name;
private int age;
// 构造方法1:无参数
public Person() {
this.name = "未知姓名";
this.age = 0;
}
// 构造方法2:仅初始化name
public Person(String name) {
this.name = name;
this.age = 0; // 默认年龄为0
}
// 构造方法3:初始化name和age
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter方法省略...
}
创建对象时,编译器会根据传入的参数自动匹配对应的构造方法:
Person p1 = new Person(); // 调用无参数构造方法
Person p2 = new Person("李四"); // 调用Person(String)构造方法
Person p3 = new Person("王五", 30); // 调用Person(String, int)构造方法
构造方法的相互调用
为了避免代码重复,一个构造方法可以通过this(参数)调用另一个构造方法,这种方式称为构造方法的链式调用。
示例:构造方法间的调用
public class Person {
private String name;
private int age;
// 完整参数的构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 仅name参数的构造方法,调用完整参数构造方法
public Person(String name) {
this(name, 18); // 调用Person(String, int),默认年龄18
}
// 无参数构造方法,调用单参数构造方法
public Person() {
this("未知姓名"); // 调用Person(String)
}
}
这种设计的好处是:
- 减少代码重复,提高维护性
- 确保初始化逻辑的一致性
- 新增初始化步骤时只需修改一个构造方法
注意:
this(...)必须是构造方法的第一条语句,否则会编译错误。
对象初始化顺序
当创建对象时,Java会按照特定的顺序进行初始化:
- 初始化字段的默认值或显式赋值(字段定义时的初始化)
- 执行构造方法中的代码
示例:初始化顺序演示
public class Person {
// 字段显式初始化
private String name = "初始化值";
private int age = 10;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Person person = new Person("张三", 25);
System.out.println(person.name); // 输出"张三"(构造方法覆盖了初始值)
System.out.println(person.age); // 输出25(构造方法覆盖了初始值)
}
}
在这个例子中:
- 字段首先被初始化为
name="初始化值",age=10 - 然后执行构造方法,将
name改为"张三",age改为25 - 最终对象的字段值由构造方法确定
注意事项
- 参数验证:在构造方法中可以对参数进行合法性检查,避免创建无效对象
public Person(String name, int age) {
// 验证参数
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("姓名不能为空");
}
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在0-150之间");
}
this.name = name;
this.age = age;
}
提供必要的构造方法重载:根据使用场景提供不同参数组合的构造方法,但不宜过多
使用构造方法链:通过
this(...)调用减少代码重复
综合示例:构造方法的实际应用
import java.time.LocalDate;
public class Student {
private String id; // 学号(必填)
private String name; // 姓名(必填)
private int grade; // 年级(可选,默认1)
private LocalDate enrollDate; // 入学日期(可选,默认当前日期)
// 完整参数构造方法
public Student(String id, String name, int grade, LocalDate enrollDate) {
// 参数验证
if (id == null || id.isBlank()) {
throw new IllegalArgumentException("学号不能为空");
}
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("姓名不能为空");
}
if (grade < 1 || grade > 12) {
throw new IllegalArgumentException("年级必须在1-12之间");
}
this.id = id;
this.name = name;
this.grade = grade;
this.enrollDate = enrollDate;
}
// 省略入学日期的构造方法
public Student(String id, String name, int grade) {
this(id, name, grade, LocalDate.now()); // 调用完整构造方法,默认当前日期
}
// 省略年级和入学日期的构造方法
public Student(String id, String name) {
this(id, name, 1); // 调用上一个构造方法,默认1年级
}
// getter方法
public String getId() { return id; }
public String getName() { return name; }
public int getGrade() { return grade; }
public LocalDate getEnrollDate() { return enrollDate; }
public static void main(String[] args) {
Student s1 = new Student("S001", "张三", 3);
System.out.println(s1.getName() + "," + s1.getGrade() + "年级");
Student s2 = new Student("S002", "李四");
System.out.println(s2.getName() + "," + s2.getGrade() + "年级");
}
}
总结
- 掌握构造方法的使用,构造方法用于在创建对象时初始化字段:
- 名称与类名相同且无返回值
- 未显式定义构造方法时,编译器会生成默认无参数构造方法
- 构造方法可以重载,通过参数列表区分不同的构造方法
- 了解即可:
- 构造方法之间可以通过
this(...)相互调用,减少代码重复 - 对象初始化顺序:先初始化字段,再执行构造方法
- 构造方法之间可以通过
Java面向对象基础——2.构造方法的更多相关文章
- 085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用
085 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 04 构造方法调用 本文知识点:构造方法调用 说明:因为时间紧张,本人写博客过程中只是 ...
- 084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字
084 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 03 构造方法-this关键字 本文知识点:构造方法-this关键字 说明:因为时间紧 ...
- 083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法
083 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 02 构造方法-带参构造方法 本文知识点:构造方法-带参构造方法 说明:因为时间紧张, ...
- 082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法
082 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 02 构造方法介绍 01 构造方法-无参构造方法 本文知识点:构造方法-无参构造方法 说明:因为时间紧张, ...
- 【重走Android之路】【Java面向对象基础(三)】面向对象思想
[重走Android之路][基础篇(三)][Java面向对象基础]面向对象思想 1 面向对象的WWH 1.1 What--什么是面向对象 首先,要理解“对象”.在Thinkin ...
- 【重走Android之路】【Java面向对象基础(一)】数据类型与运算符
[重走Android之路][基础篇(一)][Java面向对象基础]数据类型与运算符 1.数据类型介绍 在Java中,数据类型分为两种:基本数据类型和引用类型. 基本数据类型共8种,见下表: 基本数 ...
- 086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结
086 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 03 面向对象基础总结 01 面向对象基础(类和对象)总结 本文知识点:面向对象基础(类和对象)总结 说明 ...
- 【重走Android之路】【Java面向对象基础(二)】细说String、StringBuffer和StringBuilder
[重走Android之路][基础篇(二)][Java面向对象基础]细说String.StringBuffer和StringBuilder 1.String String是Java中的一个final ...
- 081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字
081 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 06 new关键字 本文知识点:new关键字 说明:因为时间紧张,本人写博客过程中只是 ...
- 080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则
080 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 05 单一职责原则 本文知识点:单一职责原则 说明:因为时间紧张,本人写博客过程中只是 ...
随机推荐
- Redis实战-缓存穿透、缓存雪崩、缓存击穿和缓存并发的区别和解决方案
正常处理流程 客户端请求正常的时候,先读缓存,如果数据命中,则返回缓存的值:否则,把从存储层中读取出来的数据缓存至缓存,同时返回客户端.但是,为了保证系统高可用和高性能,设计一个缓存系统时必须考虑 ...
- IIS设置发布公告页面
IIS原有站点停用 IIS新增里新增一个站点,端口及域名和原有站点一致 新增公告提示页面,如:index.html 新增web.config文件,并设置web.config 1 <system. ...
- Astah Community安装教程及使用说明(包括括菜单命令解释、操作向导说明、快捷命令说明)
一.安装教程: 1.双击下载好的文件,允许安装(现在官网已经停刊免费的社区版了,如果想要下载社区版需要从其他地方寻找资源) 2.选择安装的语言,English,点击OK 3.next,接受协议,nex ...
- .net入行第4年
没错 我在2024-06-28发布了我的三年.net感想 时隔一年,我又来分享了 这一年的时间真的没有经过逛博客园 ,每天都在忙 首先,恭喜一下自己 -- 我现在也算是一个小老板了(虽然主业还是程序员 ...
- 直击运维痛点,大数据计算引擎 EasyMR 的监控告警设计优化之路
当企业的业务发展到一定的阶段时,在系统中引入监控告警系统来对系统/业务进行监控是必备的流程.没有监控或者没有一个好的监控,会导致开发人员无法快速判断系统是否健康:告警的实质则是"把人当服务用 ...
- 袋鼠云数栈基于CBO在Spark SQL优化上的探索
原文链接:袋鼠云数栈基于CBO在Spark SQL优化上的探索 一.Spark SQL CBO选型背景 Spark SQL的优化器有两种优化方式:一种是基于规则的优化方式(Rule-Based Opt ...
- kubernetes源码解析
下载并且编译 git clone https://github.com/kubernetes/kubernetes.git cd kubernetes make cd _output 查看编译产物
- C#.Net筑基-泛型T & 协变逆变
01.什么是泛型? 泛型(Generics)是C#中的一种强大的强类型扩展机制,在申明时用"占位符"类型参数"T"定义一个"模板类型",比较 ...
- JavaScript中如何遍历对象?
JavaScript中如何遍历对象? 今天来点稍微轻松的话题,如何在JavaScript中遍历对象,在平常的工作中,遍历对象是很常见的操作,javascript提供了多种方法来遍历对象的属性.这些方法 ...
- java--xml约束、tomcat服务器
xml约束 XML语法: 规范的xml文件的基本编写规则.(由w3c组织制定的) XML约束: 规范XML文件数据内容格式的编写规则.(由开发者自行定义) DTD约束 DTD约束:语法相对简单,功能也 ...