文章目录
- 认识面向对象
- 如何创建对象
- 构造器(Constructor)
- 构造器的重载
- 构造器的注意事项
- Getter和Setter方法
- 如何快速生成构造器,getter和setter
- IDEA的Generate功能
- Lombok插件
- 面向对象的三大特征之封装
- 封装(Encapsulation)

面向对象(Object-Oriented Programming,简称OOP)是一种编程思想,它通过将现实世界中的事物(对象)模拟到程序中,从而使程序的设计、开发和维护更加清晰和高效。
认识面向对象
前面有提到面向对象通过将现实世界中的对象模拟到程序中,把现实中的事物和程序中的代码“对应”起来,这样就更容易理解和维护。
在Java中,万物皆对象。
在面向对象编程中,“对象”是现实世界中事物的抽象。可以把它理解为我们生活中的一个具体事物,比如“汽车”“学生”“手机”。每个对象都有它的属性(像汽车的颜色、型号,学生的名字、年龄)和行为(像汽车的加速、刹车,学生的学习、考试)。
那么,对象,是如何实现的,这就需要用到类,“类”是对一类事物的抽象和定义,它就像是一个模板或蓝图,用来描述一类对象的属性和行为。例如,定义一个“汽车”类,这个类中包含所有汽车的共性,比如颜色、型号、加速和刹车等行为。基于这个类,你可以创建多个“汽车”对象,每个汽车对象有不同的颜色和型号,但它们共享相同的行为。
类可以理解成对象的设计图,或者对象的模板。
如何创建对象
在Java中,创建对象的过程是通过类来实例化对象。对象是类的实例,而类则是对某一类事物的抽象,定义了这些事物的属性和行为。
创建一个对象的基本步骤包括:
- 声明对象:指定对象的类型(类名)。
- 实例化对象:通过
new
关键字来创建对象。 - 调用构造方法:构造方法用于初始化对象的状态(即属性)。
我们先定义一个简单的Car
类,然后通过该类创建一个Car
对象。
步骤 1:定义一个类(Car)
class Car {// 属性:品牌、速度String brand;int speed;// 构造方法:初始化属性public Car(String brand, int speed) {this.brand = brand;this.speed = speed;}// 方法:加速public void accelerate() {speed += 10;System.out.println("当前速度:" + speed);}// 方法:显示车的品牌public void displayBrand() {System.out.println("这辆车的品牌是:" + brand);}
}
步骤 2:创建对象并调用方法
创建对象:Car myCar =new Car("BMW",0);
调用对象的方法:myCar.displayBrand()
,myCar.accelerate()
public class Main {public static void main(String[] args) {// 创建对象Car myCar = new Car("BMW", 0); // 使用Car类的构造方法,创建一个BMW品牌的汽车对象,初始速度为0// 调用对象的方法myCar.displayBrand(); // 输出:这辆车的品牌是:BMWmyCar.accelerate(); // 输出:当前速度:10myCar.accelerate(); // 输出:当前速度:20}
}
解释:
-
声明对象:
Car myCar
; 这一行声明了一个Car
类型的对象myCar
。这里的Car是对象的类型,也可以称为类。 -
实例化对象:
myCar = new Car("BMW", 0);
使用new关键字实例化了一个Car
类的对象,并且通过构造方法给它初始化了brand
(品牌)为BMW
,speed
(速度)为0。 -
构造方法:
Car(String brand, int speed)
是Car
类的构造方法,它在我们创建myCar
对象时被调用,用来初始化myCar
的brand
和speed
属性。 -
调用方法:通过对象
myCar
,我们调用了displayBrand()
方法显示汽车品牌,调用了accelerate()
方法来加速,并打印出当前速度。
构造器(Constructor)
构造器是一个特殊的方法,用来在创建对象时初始化对象的状态(即给对象的属性赋值)。构造器的名字必须和类的名字相同,而且没有返回值。
构造器的基本特点:
- 名字与类名相同。
- 没有返回值(连
void
都没有)。 - 可以有多个构造器(称为构造器的重载),通过不同的参数来初始化对象的不同属性。
- 分为
有参构造
和无参构造
。
class Person {String name; // 名字int age; // 年龄double height; // 身高// 构造方法:初始化Person对象的属性public Person(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}// 方法:显示个人信息public void displayInfo() {System.out.println("姓名:" + name + ", 年龄:" + age + ", 身高:" + height + "米");}
}public class Main {public static void main(String[] args) {// 使用构造方法创建Person对象Person person = new Person("张三", 25, 1.75);// 调用对象方法,显示个人信息person.displayInfo(); // 输出:姓名:张三, 年龄:25, 身高:1.75米}
}
Person
类的构造器Person(String name, int age, double height)
用于初始化Person
对象的属性。- 在创建
person
对象时,通过构造器传入参数来给name
、age
和height
赋值。 - 然后调用
displayInfo()
方法来显示这个人的信息。
构造器的重载
Java允许类有多个构造器,这叫做构造器重载。构造器重载是通过不同参数来区分不同的构造器。一般来说,分为有参构造器
和无参构造器
。
class Car {String brand;int speed;// 默认构造器,没有参数,无参构造器public Car() {this.brand = "未知品牌";this.speed = 0;}// 带参数的构造器,有参构造器public Car(String brand, int speed) {this.brand = brand;this.speed = speed;}// 加速方法public void accelerate() {speed += 10;System.out.println("当前速度:" + speed);}// 显示品牌方法public void displayBrand() {System.out.println("这辆车的品牌是:" + brand);}
}public class Main {public static void main(String[] args) {// 使用默认构造器创建对象Car car1 = new Car();car1.displayBrand(); // 输出:这辆车的品牌是:未知品牌car1.accelerate(); // 输出:当前速度:10// 使用带参数的构造器创建对象Car car2 = new Car("BMW", 0);car2.displayBrand(); // 输出:这辆车的品牌是:BMWcar2.accelerate(); // 输出:当前速度:10}
}
构造器的注意事项
1.在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
2.一旦定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构造器。
Getter和Setter方法
Getter方法用于获取对象的属性值,Setter方法用于设置对象的属性值。它们通常用于封装类中的私有属性(即使用private
修饰符),以控制属性的访问。
为什么使用Getter和Setter?
- 控制访问权限:可以控制属性的读取和修改,比如对属性进行检查(例如限制某个数值的范围)。
- 数据封装:通过隐藏类的具体实现,外界只通过公开的接口(
Getter
和Setter
)来访问数据,从而确保数据的安全性。
class Person {private String name; // 私有属性private int age; // 私有属性private double height; // 私有属性// 构造方法:初始化Person对象的属性public Person(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}// Getter方法:获取名字public String getName() {return name;}// Setter方法:设置名字public void setName(String name) {this.name = name;}// Getter方法:获取年龄public int getAge() {return age;}// Setter方法:设置年龄public void setAge(int age) {if (age > 0) {this.age = age;} else {System.out.println("年龄必须大于0");}}// Getter方法:获取身高public double getHeight() {return height;}// Setter方法:设置身高public void setHeight(double height) {if (height > 0) {this.height = height;} else {System.out.println("身高必须大于0");}}// 方法:显示个人信息public void displayInfo() {System.out.println("姓名:" + name + ", 年龄:" + age + ", 身高:" + height + "米");}
}public class Main {public static void main(String[] args) {// 使用构造方法创建Person对象Person person = new Person("李四", 30, 1.80);// 使用Getter方法获取属性值System.out.println("名字:" + person.getName()); // 输出:名字:李四System.out.println("年龄:" + person.getAge()); // 输出:年龄:30System.out.println("身高:" + person.getHeight()); // 输出:身高:1.8// 使用Setter方法修改属性值person.setName("王五");person.setAge(35);person.setHeight(1.85);// 修改后再显示个人信息person.displayInfo(); // 输出:姓名:王五, 年龄:35, 身高:1.85米}
}
1.Setter方法:
setName(String name)
:用于设置name
属性的值。setAge(int age)
:用于设置age
属性的值,并且在设置时对年龄值进行检查,确保年龄大于0。setHeight(double height)
:用于设置height
属性的值,并且检查身高是否大于0。
2.Getter方法:getName()
:用于获取name
属性的值。getAge()
:用于获取age
属性的值。getHeight()
:用于获取height
属性的值。
通过这些方法,我们能够安全地访问和修改Person
对象的属性,而且可以对属性的修改进行控制(例如,检查年龄和身高是否有效)。
如何快速生成构造器,getter和setter
我们定义一个类时,经常需要编写常用方法:构造器方法(无参构造器,有参构造器),getter,setter方法,这几个方法都是最常见的。然而,在Java开发中,手动编写构造器、getter和setter方法会比较繁琐,而现代IDE(如IntelliJ IDEA)提供了一些功能,可以帮助我们快速生成这些方法。除了IDEA之外,还有一些工具(如Lombok插件)可以简化这个过程。
IDEA的Generate功能
鼠标右键,点击空白处,选中Generate
,也可以选择快捷键Alt+Insert
我们常用的是Getter and Setter
和Constructor
,当然也可以根据需求,单独选择Getter
或者Setter
。
Ctrl+A
全选,点击OK,一键生成所有Getter
和Setter
方法
构造器也一样,选择想要的,或者全选,快速生成构造器方法(有参)
如果需要无参构造器,就点击Select None
//定义一个学生类
public class Student {private String name;private Integer age;private double socre;public Student(String name, Integer age, double socre) {this.name = name;this.age = age;this.socre = socre;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public double getSocre() {return socre;}public void setSocre(double socre) {this.socre = socre;}
}
Lombok插件
Lombok的出现再次简化了代码,Lombok是一个非常流行的Java库,它可以通过注解自动生成常用的代码(如构造器、getter
和setter
方法、toString
等),大大简化代码的编写。
1.安装Lombok插件:
在IDEA中,首先需要安装Lombok插件。
打开File -> Settings
(在Mac上是IntelliJ IDEA
-> Preferences
)。
选择Plugins
,搜索Lombok
,然后点击安装插件。
安装完毕后,重启IDEA。
2.添加Lombok的依赖:
- 在
pom.xml
(如果你使用Maven
)中,添加Lombok的依赖:
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version> <!-- 使用最新的Lombok版本 --><scope>provided</scope>
</dependency>
- 如果你使用
Gradle
,可以在build.gradle
中添加:
dependencies {compileOnly 'org.projectlombok:lombok:1.18.24' // 使用最新版本annotationProcessor 'org.projectlombok:lombok:1.18.24'
}
如果你没有使用Maven或者Gradle(因为可能没那么快接触到),我们还有其他方法,下面会讲到
3.使用Lombok注解:
Lombok提供了注解,可以自动生成构造器、getter、setter等。以下是常见的注解:
@Getter
:自动生成getter
方法。@Setter
:自动生成setter
方法。@AllArgsConstructor
:生成包含所有成员变量的构造器,有参构造器。@NoArgsConstructor
:生成无参数的构造器,无参构造器。@ToString
:自动生成toString
方法。@Data
:组合注解,自动生成getter
、setter
、toString
、equals
、hashCode
方法以及构造器。
如果你没有使用Maven或者Gradle
(因为可能没那么快接触到),我们可以这样做:
我们一般会添加的是@Data
注解,因为可以基本全部的方法。
首先在类上写上@Data
,不管会不会报错
鼠标靠近@Data
,它会自动弹出Import class
,点击它,会自动导入它,为什么要这么做,因为Java的包很多,包名很长,我们不可能记住所有的,可以依靠IDEA帮我们提供。
包导入成功后,不会再显示报错了,后面添加@AllArgsConstructor
,@NoArgsConstructor
时就会有提示,且不会报错,我们输入一个“@A”或“@N”,它就会提示出来。
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;@AllArgsConstructor // 生成带参数的构造器
@Getter // 生成所有属性的getter方法
@Setter // 生成所有属性的setter方法
public class Person {private String name;private int age;private double height;
}
在上述代码中,Lombok会自动为Person
类生成:
- 一个带有
name
、age
和height
参数的构造器。 - 对所有属性(
name
、age
、height
)生成getter
和setter
方法。
因此,以上代码会生成如下的内容:
public class Person {private String name;private int age;private double height;// 构造器public Person(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}// Getter方法public String getName() {return name;}public int getAge() {return age;}public double getHeight() {return height;}// Setter方法public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}public void setHeight(double height) {this.height = height;}// 其他方法,例如toString,equals等...
}
面向对象的三大特征之封装
面向对象的三大特征是:封装,继承,多态。这三大特性是面向对象编程的核心思想,每一个特性都有其独特的作用和优点。在这里,我们先说封装。
封装(Encapsulation)
封装是将对象的状态(属性)和行为(方法)捆绑在一起,并且对外界隐藏实现的细节。封装的目的是为了提高代码的安全性和可维护性,避免直接修改对象的内部数据。
下面用一个汽车类的代码进行解释
class Car {private String brand; // 私有属性,外界无法直接访问private int speed;// 构造方法,用来初始化属性public Car(String brand, int speed) {this.brand = brand;this.speed = speed;}// 公共的getter和setter方法,用于访问和修改私有属性public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public int getSpeed() {return speed;}public void setSpeed(int speed) {if (speed > 0) {this.speed = speed;} else {System.out.println("速度必须大于零!");}}// 方法:加速public void accelerate() {speed += 10;System.out.println("汽车加速了,当前速度:" + speed);}
}public class Main {public static void main(String[] args) {Car myCar = new Car("BMW", 0);myCar.setSpeed(60); // 通过setter方法设置速度System.out.println("我的车品牌是:" + myCar.getBrand());myCar.accelerate(); // 调用加速方法}
}
在这样一个汽车类中,我们将所需要处理的数据(汽车的品牌brand
和汽车的速度speed
),以及处理数据的方法设计到一个对象中,这就实现了封装
。
同时,有没有发现,有些使用private
修饰,而有些使用了public
修饰,这就涉及到了封装的设计规范。
封装的设计规范是:合理隐藏,合理暴露。
封装的好处是信息隐藏,减少外界对对象内部细节的依赖,提高代码的安全性和可维护性。